﻿using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using DICE_GS;

public struct CreateCardInfo
{
	public int sid;
	public int unitId;
	public int slot;
	public int nLevel;

	public CreateCardInfo(int _sid, int _unitId, int _slot, int _nLevel)
	{
		sid = _sid;
		unitId = _unitId;
		slot = _slot;
		nLevel = _nLevel;
	}
}

[System.Serializable]
public class PlayerDeck
{
	public List<UnitCard> cards = new List<UnitCard>();
	public List<UnitCard> activeList = new List<UnitCard>();
	public List<UnitCard> deactiveList = new List<UnitCard>();	
	public UnitCard curActiveCard;
	public bool isCardLocked;
	public MoveDir anchor;
	public bool cardLockEffectCreated;
	public GameObject cardDeck;
	public int activeSlot;
	//public bool isUnitCardActivateChanged;
	
	
	public void SetEnableAllCardScaleChange(bool bEnable)
	{
		foreach(UnitCard card in cards)
		{
			card.unitCardScript.isDisabled = !bEnable;
			if(card.unitCardScript.isDisabled)
			{
				card.unitCardScript.ScaleChange(false);
				card.unitCardScript.isActive = false;
			}
			else
				card.unitCardScript.isActive = true;
		}
	}
	
	public bool IsMirrorSide()
	{
		if(anchor == MoveDir.BottomRight || anchor == MoveDir.TopRight)
			return true;
		return false;
	}
	
	public void GlowFirstActiveCard()
	{
		if(activeList.Count>0)
			activeList[0].StartGlow();
	}

	public void StopGlowFirstActiveCard()
	{
		if(activeList.Count>0)
			activeList[0].StopGlow();
	}
	
	public void SetCurActiveCard(UnitCard card)
	{
		curActiveCard = card;
	}
	
	public void ClearCurActiveCard()
	{
		curActiveCard = null;
	}
}

[System.Serializable]
public class UnitActivationInfo
{
	public bool isChanged;
	public List<int> activeList = new List<int>();
	public List<int> deactiveList = new List<int>();
	public Dictionary<int , int > deactiveRemainTurn = new Dictionary<int, int>();
}

[System.Serializable]
public class UnitActivationInfoPerCombat
{
	public List<int> activeListTemp = new List<int>();
	public Dictionary<int , UnitActivationInfo> info = new Dictionary<int, UnitActivationInfo>();
	public UnitActivationInfo CurCombatInfo()
	{
		int count = CardManager.Instance.battleManagerCombatCount;
		while(!info.ContainsKey(count))
		{
			if(count==0)
				break;
			count--;
		}
		return info[count];
	}
	
	public UnitActivationInfo CurInfo()
	{
		return info[0];
	}
	
	public bool IsNextCombatCardChanged()
	{
		int nextCount = CardManager.Instance.battleManagerCombatCount + 1;
		if(!info.ContainsKey(nextCount))
			return true;
		return info[nextCount].isChanged;
	}
	
	public bool IsCurCombatCardChanged()
	{
		return CurCombatInfo().isChanged;
	}
	
	public int GetDeactiveRemainTurn(int slot)
	{
		for(int combatCount = CardManager.Instance.maxCombatCount; combatCount>=0 ; combatCount-- )
		{
			if( info.ContainsKey(combatCount) )
			{
				if( info[combatCount].deactiveRemainTurn.ContainsKey(slot) )
					return info[combatCount].deactiveRemainTurn[slot];
			}
		}
		
		Debug.LogError(" GetDeactiveRemainTurn find error  slot="+slot);
		return 99;
	}
	
//	public UnitActivationInfo NextCombatInfo()
//	{
//		return info[BattleManager.Instance.combatCount+1];
//	}
	
	public void SetCurCombatInfoToNormal()
	{
		info[0].isChanged = false;
		info[0].activeList = CurCombatInfo().activeList.GetRange(0, CurCombatInfo().activeList.Count);
		info[0].deactiveList = CurCombatInfo().deactiveList.GetRange(0, CurCombatInfo().deactiveList.Count);
		info[0].deactiveRemainTurn = new Dictionary<int, int>( CurCombatInfo().deactiveRemainTurn );
	}
	
	public void ClearAllCombatInfo()
	{
		for(int combatCount= CardManager.Instance.battleManagerCombatCount; combatCount>=1; combatCount--)
		{
			Clear(combatCount);
		}
	}
	
	public void Clear(int combatCount)
	{
		activeListTemp.Clear();
		
		if( !info.ContainsKey(combatCount) )
			info.Add (combatCount, new UnitActivationInfo() );
		
		info[combatCount].activeList.Clear ();
		info[combatCount].deactiveList.Clear ();
		info[combatCount].deactiveRemainTurn.Clear ();
		info[combatCount].isChanged = false;
	}
	
	public void AddActiveTemp(int combatCount, int slot)
	{
		activeListTemp.Add (slot);
	}
	
//	public void AddActiveReal(int combatCount, int slot)
//	{
//		info[combatCount].activeList.Add (slot);
//	}	

	public void AddDeactive(int combatCount, int slot, int remainTurn)
	{
		info[combatCount].deactiveList.Add (slot);
		info[combatCount].deactiveRemainTurn.Add(slot, remainTurn);
	}
	
	public int GetRemainTurn(int combatCount, int slot)
	{
		return info[combatCount].deactiveRemainTurn[slot];
	}
	
	public bool CheckDiffActive(int combatCount, bool isNonBattle)
	{
		bool isChanged = false;

		if(combatCount>=1)
		{
			int checkCombatCount = combatCount - 1;
			glog.debug("checkCombatCount="+checkCombatCount);
			if(checkCombatCount>=1)
			{
				while(!info.ContainsKey(checkCombatCount) || info[checkCombatCount].activeList.Count==0)
				{
					checkCombatCount--;
					glog.debug("combat search back "+checkCombatCount);
					if(checkCombatCount==0)
					{
						Debug.LogError("checkCombatCount is Zero...break");
						break;
					}
				}
			}
			if( activeListTemp.Count != info[checkCombatCount].activeList.Count)
			{
				isChanged = true;
				glog.debug(combatCount+"  CheckDiffActive isChanged = "+isChanged);
				info[combatCount].activeList = activeListTemp.GetRange(0, activeListTemp.Count);
				info[combatCount].isChanged = isChanged;
				return isChanged;
			}
			int i = 0;
			foreach( int slot in activeListTemp)
			{
				if(slot != info[checkCombatCount].activeList[i])
				{
					isChanged = true;
					break;
				}
				i++;
			}
			info[combatCount].activeList = activeListTemp.GetRange(0, activeListTemp.Count);
			info[combatCount].isChanged = isChanged;
			glog.debug(combatCount+"  CheckDiffActive isChanged = "+isChanged);
			return isChanged;		
		}
		else
		{
			if(isNonBattle)
			{
				info[0].activeList = activeListTemp.GetRange(0, activeListTemp.Count);
				info[0].isChanged = false;
				return false;
			}
			else
			{
				if( activeListTemp.Count != info[0].activeList.Count)
					isChanged = true;
				else
				{
					int i = 0;
					foreach( int slot in activeListTemp)
					{
						if(slot != info[0].activeList[i])
						{
							isChanged = true;
							break;
						}
						i++;
					}
				}
				info[0].activeList = activeListTemp.GetRange(0, activeListTemp.Count);
				info[0].isChanged = isChanged;
				glog.debug("0 during abttle CheckDiffActive isChanged = "+isChanged);
				return isChanged;	
			}
		}			
	}

}


public class CardManager : MonoBehaviour {
	
	private static CardManager instance;

	public static CardManager Instance{
		get{
			return instance;
		}
	}	

	Dictionary<string, LeanTweenType> strLeanTweenType = new Dictionary<string, LeanTweenType>()
	{
		{"easeInSine", LeanTweenType.easeInSine },
		{"easeOutSine", LeanTweenType.easeOutSine },
		{"easeOutBounce", LeanTweenType.easeOutBounce },
	};
	
	public GameObject [] cardDeck;
	public GameObject  cardDeck_boss;
	//public GameObject  [] bossEmptyCardDeck;
	public GameObject ingameCardPrefab;
	public GameObject skillNameShowPrefab;
	public GameObject ingameTextShowPrefab;
	public GameObject centerAnchor;
	Dictionary<int, PlayerDeck> playerDeck = new Dictionary<int, PlayerDeck>();
	public PlayerDeck myDeck;
	public PlayerDeck bossDeck;
	
	public Transform [] cardPos;
	public Transform [] bossCardPos;
	public Transform moveMidPoint;
	
	public Transform popPosLeft;
	public Transform popPosRight;
	
	public int mySID;
	public int bossSID;
	
	Dictionary<int, UnitActivationInfoPerCombat> unitActivationInfo = new Dictionary<int, UnitActivationInfoPerCombat>();
	List<int> deactiveCheckList = new List<int>();
	List<int> activeCheckList = new List<int>();
	List<UnitCard> shouldMoveToActiveList = new List<UnitCard>();
	int activeListIndex;
	public bool isCoBattleEndRunning;
	public bool isCardWinAndBreakDone;
	public bool bDoneSetUnitActivationInfo_NonBattle = true;
	public bool isAddedTeam;
	
	public bool isElementFX;
	
	//public Texture [] elementWinTexture;
	public Texture [] elementRockPaperTexture;
	
	public float popCardTime = 0.3f;
	
	public GameObject fxCardDestroyPrefab;
	List<GameObject> fxCardDestroyObjList = new List<GameObject>();
	//public ParticleSystem fxCardDestroyPS;
	//public float fxCardDestroyObj_startSize;
	//public float [] fxCardDestroyObj_childStartSize;
	//public ParticleSystem [] fxCardDestroyPS_child;
	
	public GameObject fxWinPrefab;
	public GameObject fxWinObj;
	public ParticleSystem fxWinPS;
	public float fxWinPS_startSize;
	
	public GameObject fxDeactiveCountPrefab;
	public GameObject ingameTextShowGo;
	public GameObject skillNameShowGo;
	public GameObject ingameTextShowGo1;
	public GameObject skillNameShowGo1;
	public GameObject ingameTextShowGo2;
	public GameObject skillNameShowGo2;
	
	public int originalDepth;
	public bool bCheckOtherPlayerCardMoveDone;
	public int maxCombatCount;
	public GameObject cardLockPrefab;
	List<CreateCardInfo> createCardInfo = new List<CreateCardInfo>();
	List<PC_OP_UPDATE_TEAM_DATA> updateTeamDataReserve = new List<PC_OP_UPDATE_TEAM_DATA>();
	List<PC_OP_UNIT_ACTIVATION_INFO> unitActiInfoReserve = new List<PC_OP_UNIT_ACTIVATION_INFO>();
	public int battleManagerCombatCount;
	static GameObject cardSkillEffectPrefab;
	List<GameObject> cardSkillEffectList = new List<GameObject>();

	//public GameObject fxElementWin;
	//public GameObject fxElementLose;
	//public GameObject prefab_fxElementWin;
	public GameObject prefab_fxCardRebirth;

	//GameObject fxElementSky;
	//GameObject fxElementEarth;
	//GameObject fxElementOcean;
	//GameObject prefab_fxElementSky;
	//GameObject prefab_fxElementEarth;
	//GameObject prefab_fxElementOcean;


	public GameObject [] fxElementWinPrefab;
	public GameObject [] fxElementLosePrefab;

	public GameObject [] fxElementWin;
	public GameObject [] fxElementLose;

	void Awake()
	{
		instance = this;
		ingameCardPrefab=Resources.Load ("Prefabs/UI/IngameCard_New") as GameObject;
		originalDepth = ingameCardPrefab.GetComponent<UIPanel>().depth;
		fxElementWinPrefab = new GameObject[4];
		fxElementLosePrefab = new GameObject[4];
		fxElementWin = new GameObject[4];
		fxElementLose = new GameObject[4];
	}
	
	// Use this for initialization
	void Start () {
	
	}
	
	public void MakeCardEffect()
	{
		//fxCardDestroyObj = Instantiate(fxCardDestroyPrefab) as GameObject;
		//fxCardDestroyPS = fxCardDestroyObj.GetComponent<ParticleSystem>();
		//fxCardDestroyObj.SetActive(false);
		//glog.debug("fxCardDestroyObj.transform.childCount="+fxCardDestroyObj.transform.childCount);
		//fxCardDestroyObj_childStartSize = new float[fxCardDestroyObj.transform.childCount];
		//fxCardDestroyPS_child = new ParticleSystem[fxCardDestroyObj.transform.childCount];
		//fxCardDestroyObj_startSize = fxCardDestroyPS.startSize;
		//int i=0;
//		foreach(Transform child in fxCardDestroyObj.transform)
//		{
//			ParticleSystem ps = child.gameObject.GetComponent<ParticleSystem>();
//			fxCardDestroyPS_child[i] = ps;
//			fxCardDestroyObj_childStartSize[i] = ps.startSize;
//			i++;
//		}
				
		fxWinObj = Instantiate(fxWinPrefab) as GameObject;
		fxWinPS = fxWinObj.GetComponent<ParticleSystem>();
		fxWinPS_startSize = fxWinPS.startSize;
		fxWinPS.startSize = fxWinPS_startSize * popPosLeft.localScale.x;
		
		
		ingameTextShowGo1 = Instantiate( ingameTextShowPrefab) as GameObject;
		ingameTextShowGo1.SetActive(false);
		ingameTextShowGo2 = Instantiate( ingameTextShowPrefab) as GameObject;
		ingameTextShowGo2.SetActive(false);
		
		skillNameShowGo1 = NGUITools.AddChild( centerAnchor, skillNameShowPrefab);		
		skillNameShowGo1.SetActive(false);
		skillNameShowGo2 = NGUITools.AddChild( centerAnchor, skillNameShowPrefab);		
		skillNameShowGo2.SetActive(false);		

		prefab_fxCardRebirth = Resources.Load ("Prefabs/FX/FX_CardRebirth") as GameObject;

//		prefab_fxElementWin = Resources.Load ("Prefabs/FX/FX_ElementWin") as GameObject;
//		prefab_fxElementSky = Resources.Load ("Prefabs/FX/fx_CardElmentSky") as GameObject;
//		prefab_fxElementEarth = Resources.Load ("Prefabs/FX/fx_CardElmentEarth") as GameObject;
//		prefab_fxElementOcean = Resources.Load ("Prefabs/FX/fx_CardElmentOcean") as GameObject;
		fxElementWinPrefab[(int)element.ocean] = Resources.Load ("Prefabs/FX/fx_CardElmentOcean_WIN") as GameObject;
		fxElementWinPrefab[(int)element.sky] = Resources.Load ("Prefabs/FX/fx_CardElmentSky_WIN") as GameObject;
		fxElementWinPrefab[(int)element.earth] = Resources.Load ("Prefabs/FX/fx_CardElmentEarth_WIN") as GameObject;

		fxElementLosePrefab[(int)element.ocean] = Resources.Load ("Prefabs/FX/fx_CardElmentOcean") as GameObject;
		fxElementLosePrefab[(int)element.sky] = Resources.Load ("Prefabs/FX/fx_CardElmentSky") as GameObject;
		fxElementLosePrefab[(int)element.earth] = Resources.Load ("Prefabs/FX/fx_CardElmentEarth") as GameObject;
	}

	public GameObject ShowElementEffect_Lose(GameObject cardGo, int mySID, int opponentSID)
	{
		if( CurActiveCard(mySID) != null)
		{
			element curElement = CurActiveCard(mySID).elementType;
			if( curElement== element.sky || curElement== element.earth || curElement== element.ocean) 
			{
				if(fxElementLose[(int)curElement]==null)
					fxElementLose[(int)curElement] = Instantiate(fxElementLosePrefab[(int)curElement]) as GameObject;
				fxElementLose[(int)curElement].SetActive(true);
				fxElementLose[(int)curElement].transform.parent = cardGo.transform;
				fxElementLose[(int)curElement].transform.localPosition = fxElementLosePrefab[(int)curElement].transform.position;
				fxElementLose[(int)curElement].transform.localRotation = fxElementLosePrefab[(int)curElement].transform.rotation;
				fxElementLose[(int)curElement].transform.localScale = fxElementLosePrefab[(int)curElement].transform.localScale;
				return fxElementLose[(int)curElement];
			}

		}
		return null;
	}

	public GameObject ShowElementEffect_Win(GameObject cardGo, int mySID, int opponentSID)
	{
		if( CurActiveCard(mySID) != null)
		{
			element curElement = CurActiveCard(mySID).elementType;
			if( curElement== element.sky || curElement== element.earth || curElement== element.ocean) 
			{
				if(fxElementWin[(int)curElement]==null)
					fxElementWin[(int)curElement] = Instantiate(fxElementWinPrefab[(int)curElement]) as GameObject;
				fxElementWin[(int)curElement].SetActive(true);
				fxElementWin[(int)curElement].transform.parent = cardGo.transform;
				fxElementWin[(int)curElement].transform.localPosition = fxElementWinPrefab[(int)curElement].transform.position;
				fxElementWin[(int)curElement].transform.localRotation = fxElementWinPrefab[(int)curElement].transform.rotation;
				fxElementWin[(int)curElement].transform.localScale = fxElementWinPrefab[(int)curElement].transform.localScale;
				return fxElementWin[(int)curElement];
			}
			
		}
		return null;
	}

	public void ReleaseElementEffect(GameObject goEff)
	{
		if(goEff!=null)
		{
			goEff.SetActive(false);
			goEff.transform.parent = centerAnchor.transform;
		}
	}

//	public void MakeFXElementWinLose()
//	{
//		if(prefab_fxElementWin!=null) {
//			if(fxElementWin==null)
//				fxElementWin=Instantiate(prefab_fxElementWin) as GameObject;
//			if(fxElementLose==null)
//				fxElementLose=Instantiate(prefab_fxElementWin) as GameObject;
//		}
//	}

	public GameObject MakeCardRebirth()
	{
		if(prefab_fxCardRebirth !=null)
			return Instantiate(prefab_fxCardRebirth) as GameObject;
		return null;
	}

	public void ScaleChangeCardDestroyFX()
	{
//		fxCardDestroyPS.startSize = fxCardDestroyObj_startSize * popPosLeft.localScale.x;
//		int i=0;
//		foreach(ParticleSystem ps in fxCardDestroyPS_child)
//		{
//			ps.startSize = fxCardDestroyObj_childStartSize[i] * popPosLeft.localScale.x;
//			i++;
//		}		
	}
	
//	public void RestoreCardDestroyStartSize()
//	{
//		fxCardDestroyPS.startSize = fxCardDestroyObj_startSize;
//		foreach(ParticleSystem ps in fxCardDestroyPS_child)
//		{
//			ps.startSize = fxCardDestroyObj_childStartSize[i];
//		}		
//	}

	public GameObject MakeDestroyEffect(Transform cardTrans)
	{
		if(fxCardDestroyPrefab==null)
			fxCardDestroyPrefab = Resources.Load("Prefabs/FX/Fx_CardDestroy") as GameObject;
		if(fxCardDestroyPrefab!=null)
		{
			foreach(GameObject eff in fxCardDestroyObjList)
			{
				if(!eff.activeSelf)
				{
					return ActivateDestroyEff(eff, cardTrans);
				}
			}
			GameObject newEff = Instantiate(fxCardDestroyPrefab) as GameObject;
			return ActivateDestroyEff(newEff, cardTrans);
		}
		return null;
	}
	
	public GameObject ActivateDestroyEff(GameObject effGo, Transform cardTrans)
	{
		effGo.SetActive(true);
		effGo.transform.parent = cardTrans;
		effGo.transform.localPosition = fxCardDestroyPrefab.transform.position;
		effGo.transform.localRotation = fxCardDestroyPrefab.transform.rotation;
		effGo.transform.localScale = fxCardDestroyPrefab.transform.localScale;
		return effGo;
	}

	public void ClearDestroyEffect(GameObject go, GameObject unitCardGo)
	{
		StartCoroutine(CoClearDestroyEffect(go,unitCardGo));
	}

	IEnumerator CoClearDestroyEffect(GameObject go, GameObject unitCardGo)
	{
		yield return new WaitForSeconds(0.4f);
		unitCardGo.GetComponent<UIPanel>().enabled=false;
		yield return new WaitForSeconds(0.4f);

		//SoundManager.Instance.PlaySound(45);
		unitCardGo.SetActive(false);

		unitCardGo.GetComponent<UIPanel>().enabled=true;

		//yield return new WaitForSeconds(1.0f);
		go.transform.parent = instance.transform;
		go.SetActive(false);

	}

	public void ReleaseDestroyEffect(GameObject go)
	{
		StartCoroutine("CoReleaseDestroyEffect",go);
	}

	IEnumerator CoReleaseDestroyEffect(GameObject go)
	{
		go.transform.parent = instance.transform;
		yield return new WaitForSeconds(2.0f);
		go.SetActive(false);
	}
	
	public void SetEnableAllCardScaleChange(int sid, bool bEnable)
	{
		if(!playerDeck.ContainsKey(sid))
			return;
		
		playerDeck[sid].SetEnableAllCardScaleChange(bEnable);
	}
	
	public void CreateDeck(int sid)
	{
		unitActivationInfo.Add( sid, new UnitActivationInfoPerCombat() );
		//glog.debug("create deck "+sid);
		playerDeck.Add (sid, new PlayerDeck() );
	}
	
	void SetUnitCardPos(GameObject go, int nPos)
	{
		go.transform.localPosition = cardPos[nPos].transform.localPosition;
		go.transform.localRotation = cardPos[nPos].transform.localRotation;
		go.transform.localScale = cardPos[nPos].transform.localScale;
	}
	
	void ShiftBossCardDeck(int sid)
	{
		foreach( Transform trans in  bossCardPos )
		{
			Vector3 newPos = trans.localPosition;
			newPos.x -= 213;
			trans.localPosition = newPos;
		}
		
//		foreach(UnitCard card in  playerDeck[sid].cards)
//		{
//			MoveToCardPos_Detail(sid, card, 0.5f, "easeInSine", 0);
//		}
	}
	
	void SetBossUnitCardPos(GameObject go, int nPos)
	{
		go.transform.localPosition = bossCardPos[nPos].transform.localPosition;
		go.transform.localRotation = bossCardPos[nPos].transform.localRotation;
		go.transform.localScale = bossCardPos[nPos].transform.localScale;
	}	
	
	void SetCardDepth(GameObject go, int nPos)
	{
		int originalDepth = ingameCardPrefab.GetComponent<UIPanel>().depth;
		go.GetComponent<UIPanel>().depth = originalDepth - nPos;
	}
	
	public int GetCardDepth(UnitCard card)
	{
		int originalDepth = ingameCardPrefab.GetComponent<UIPanel>().depth;
		return (originalDepth - card.nPos);
	}
	
	
	GameObject CreateCard(GameObject parent )
	{
		GameObject go = NGUITools.AddChild(parent, ingameCardPrefab);
//		foreach(Transform child in go.transform)
//		{
//			child.gameObject.layer = go.layer;
//		}
		return go;
	}
	
	public void AddTeam(int sid, int slot, int unitId, CUnitData unitData, int unitLevel)
	{
		if(sid==bossSID)
		{
			ShiftBossCardDeck(sid);
			
			int nOrder = HudManager.Instance.charSidOrderDic[sid];
			GameObject go = CreateCard( centerAnchor );
			go.transform.localScale = new Vector3(0.3f,0.3f,1);
			UnitCard unitCard =  go.GetComponent<UnitCard>();
			unitCard.Init(slot, sid);
			playerDeck[sid].activeList.Add( unitCard );
			playerDeck[sid].cards.Add ( unitCard);		
			unitCard.isBossCard = true;
			unitCard.SetSlot(nOrder, slot, unitData);
			unitCard.isActivated = false;
			unitCard.SetActivate(true,0);
			int nPos = LastActivePos(sid) + 1;
			//SetBossUnitCardPos(unitCard.gameObject, nPos);
			//Vector3 newPos = unitCard.gameObject.transform.localPosition;
			//newPos.y += 700;
			//unitCard.gameObject.transform.localPosition = newPos;
			SetCardDepth(unitCard.gameObject, nPos);
			isAddedTeam = true;
			MyUnitCard myUnitCard = go.GetComponent<MyUnitCard>();
			if( myUnitCard != null )
			{
					Debug.LogError(unitLevel + "_" + unitId);
				CUnitAbilityItem plusAbility = CUnitAbilityDataManager.Instance.GetUnitAbilityData(unitLevel + "_" + unitData.unit_class);
				Debug.Log(plusAbility == null );
				myUnitCard.SetCardInfo(nOrder, unitLevel, unitData, plusAbility);
			}
			unitCard.isAddedCard = true;
			//bossEmptyCardDeck[slot-1].SetActive(false);
		}
	}

	public void CreateTeamCards(BoardPerson person)
	{
		foreach(CreateCardInfo cardInfo in createCardInfo)
		{
			if(cardInfo.sid==person.SID)
			{
				glog.debug(person.SID+" create team cards ");
				CUnitData unitData = CUnitDataManager.Instance.GetUnitData(cardInfo.unitId);
				CreateTeam(person.isMe, person.isBoss, StageManagerWrapper.IsNPCSid(person.SID), person.SID, cardInfo.slot, cardInfo.unitId, unitData, person.order, cardInfo.nLevel);
			}
		}
		foreach( var packet in unitActiInfoReserve)
		{
			if(packet.ServerID==person.SID)
			{
				glog.debug(person.SID+" unitActiInfoReserve ");
				StageManagerWrapper.manager.UpdateUnitActivationInfo(packet);
			}
		}
		foreach( var packet in updateTeamDataReserve)
		{
			if(packet.ServerID==person.SID)
			{
				glog.debug(person.SID+" updateTeamDataReserve ");
				StageManagerWrapper.manager.UpdateTeamData(packet);
			}
		}
	}

	public void ReserveUpdateTeamData(PC_OP_UPDATE_TEAM_DATA packet)
	{
		updateTeamDataReserve.Add(packet);
	}

	public void ReserveUnitActivationInfo(PC_OP_UNIT_ACTIVATION_INFO packet)
	{
		unitActiInfoReserve.Add(packet);
	}

	public void ClearReserveTeamData()
	{
		createCardInfo.Clear ();
		updateTeamDataReserve.Clear ();
		unitActiInfoReserve.Clear ();
	}

	public void ReserveCreateTeam(int sid, int slot, int unitId, int unitLevel)
	{
		//CUnitData unitData = CUnitDataManager.Instance.GetUnitData(unitId);
		//int order = person.order
		createCardInfo.Add (  new CreateCardInfo(sid,unitId,slot,unitLevel) );
	}

	public void CreateTeam(bool isMe, bool isBoss, bool isNPC, int sid, int slot, int unitId, CUnitData unitData, int order, int unitLevel)
	{
		if(!playerDeck.ContainsKey(sid))
			return;
		
		foreach( UnitCard card in playerDeck[sid].cards)
		{
			if(card.slot == slot)
				return;
		}
		
		//glog.debug("card create team  "+isMe+"  "+sid+"   "+slot);
		int nOrder = 999;
		if(!isNPC)
			nOrder = HudManager.Instance.charSidOrderDic[sid];
		
		UnitCard unitCard =  null;
		MyUnitCard myUnitCard = null;
		//LayerMask.NameToLayer("HUDUI")

		//ingameCardPrefab.layer = LayerMask.NameToLayer("HUDUI");
		
		if(isMe)
		{
			mySID = sid;
			myDeck = playerDeck[sid];
			myDeck.anchor = MoveDir.BottomLeft;
			playerDeck[sid].cardDeck = cardDeck[nOrder];
			GameObject go= CreateCard(cardDeck[nOrder]);
			unitCard =  go.GetComponent<UnitCard>();
			unitCard.Init(slot, sid);		
			unitCard.isMeCard = true;
			SetUnitCardPos(unitCard.gameObject, slot);
			SetCardDepth(unitCard.gameObject, slot);
			unitCard.SetSlot(nOrder, slot, unitData);
			myUnitCard = go.GetComponent<MyUnitCard>();
			if( myUnitCard != null )
			{
					Debug.LogError(unitLevel + "_" + unitId);
				CUnitAbilityItem plusAbility = CUnitAbilityDataManager.Instance.GetUnitAbilityData(unitLevel + "_" + unitData.unit_class);
				Debug.Log(plusAbility == null );
				myUnitCard.SetCardInfo(nOrder, unitLevel, unitData, plusAbility);
			}
		}
		else if(isBoss)
		{
			
			
			bossSID = sid;
			bossDeck = playerDeck[sid];
			
			for(int i=0; i< bossDeck.cards.Count; i++)
				ShiftBossCardDeck(sid);
			
			bossDeck.anchor = MoveDir.TopRight;
			cardDeck[nOrder] = cardDeck_boss;
			playerDeck[sid].cardDeck = cardDeck[nOrder];
			GameObject go= CreateCard(cardDeck[nOrder]);
			unitCard =  go.GetComponent<UnitCard>();
			unitCard.Init(slot, sid);			
			unitCard.isBossCard = true;
			SetBossUnitCardPos(unitCard.gameObject, slot);
			SetCardDepth(unitCard.gameObject, slot*2);
			unitCard.SetSlot(nOrder, slot, unitData);
//			bossEmptyCardDeck[0].SetActive(true);
//			bossEmptyCardDeck[1].SetActive(true);
//			bossEmptyCardDeck[2].SetActive(true);
//			bossEmptyCardDeck[3].SetActive(true);
			myUnitCard = go.GetComponent<MyUnitCard>();
			if( myUnitCard != null )
			{	
				CUnitAbilityItem plusAbility = CUnitAbilityDataManager.Instance.GetUnitAbilityData(unitLevel + "_" + unitData.unit_class);
				Debug.Log(plusAbility == null );
				myUnitCard.SetCardInfo(nOrder, unitLevel, unitData, plusAbility);
			}
		}
		else if(isNPC)
		{
			GameObject go = CreateCard( centerAnchor );
			unitCard =  go.GetComponent<UnitCard>();
			unitCard.Init(slot, sid);
			unitCard.isNPCCard = true;
			unitCard.SetSlot(nOrder, slot, unitData);
			int nPos = 0;
			//SetBossUnitCardPos(unitCard.gameObject, nPos);
			//Vector3 newPos = unitCard.gameObject.transform.localPosition;
			//newPos.y += 700;
			//unitCard.gameObject.transform.localPosition = newPos;
			SetCardDepth(unitCard.gameObject, nPos);

			 myUnitCard = go.GetComponent<MyUnitCard>();
			if( myUnitCard != null )
			{
				Debug.LogError(unitLevel + "_" + unitId);
				CUnitAbilityItem plusAbility = CUnitAbilityDataManager.Instance.GetUnitAbilityData(unitLevel + "_" + unitData.unit_class);
				Debug.Log(plusAbility == null );
				myUnitCard.SetCardInfo(nOrder, unitLevel, unitData, plusAbility);
			}
			go.transform.localScale = new Vector3(0,0,1);
			go.SetActive(false);
		}
		else
		{
			playerDeck[sid].anchor = (MoveDir)(order-1);
			playerDeck[sid].cardDeck = cardDeck[nOrder];
			GameObject go= CreateCard(cardDeck[nOrder]);
			unitCard =  go.GetComponent<UnitCard>();
			unitCard.Init(slot, sid);
			SetOtherPlayerCardPos(sid, slot, unitCard.gameObject);
//			unitCard.gameObject.GetComponent<UIPanel>().depth = 0;
			unitCard.SetSlot(nOrder, slot, unitData);
			SetCardDepth(unitCard.gameObject, 0);//-HudManager.Instance.charSidOrderDic[sid]);
			myUnitCard = go.GetComponent<MyUnitCard>();
			if( myUnitCard != null )
			{
				CUnitAbilityItem plusAbility = CUnitAbilityDataManager.Instance.GetUnitAbilityData(unitLevel + "_" + unitData.unit_class);
				Debug.Log(plusAbility == null );
				myUnitCard.SetCardInfo(nOrder, unitLevel, unitData, plusAbility);
			}
		}
		
		playerDeck[sid].activeList.Add( unitCard );
		playerDeck[sid].cards.Add ( unitCard);		
		playerDeck[sid].GlowFirstActiveCard();	
	}
	
	GameObject GetOtherPlayerCardPos(int sid, string name)
	{
		int nOrder = HudManager.Instance.charSidOrderDic[sid];
		return cardDeck[nOrder].transform.FindChild(name).gameObject;
	}
	
	void SetOtherPlayerCardPos(int sid, int pos, GameObject go)
	{
		if( StageManagerWrapper.IsNPCSid(sid) )
			return;
		if(pos==0)
		{
			go.transform.localPosition = GetOtherPlayerCardPos(sid, "CardPos").transform.localPosition;
			go.transform.localRotation = GetOtherPlayerCardPos(sid, "CardPos").transform.localRotation;
			go.transform.localScale = GetOtherPlayerCardPos(sid, "CardPos").transform.localScale;
			go.SetActive(true);
		}
		else
		{
			go.transform.localPosition = GetOtherPlayerCardPos(sid, "NextCardPos").transform.localPosition;
			go.transform.localRotation = GetOtherPlayerCardPos(sid, "NextCardPos").transform.localRotation;
			go.transform.localScale = GetOtherPlayerCardPos(sid, "NextCardPos").transform.localScale;
			go.SetActive(false);
		}		
	}

	public void EffectOnActiveCard(int sid, GameObject goEff)
	{
		if( IsActiveSlotOK(sid) )
		{
			if(playerDeck[sid].activeList.Count>0)
			{
				UnitCard card = playerDeck[sid].activeList[0];
				goEff.transform.parent = card.gameObject.transform;
				ParticleSystem [] particles = goEff.GetComponentsInChildren<ParticleSystem>();
				foreach(ParticleSystem ps in particles)
				{
					ps.startSize = ps.startSize * playerDeck[sid].cardDeck.transform.localScale.x;
					ps.Clear ();
					ps.Play ();
				}
			}
		}
	}

	public bool IsActiveSlotOK(int sid)
	{
		if( playerDeck.ContainsKey(sid) )
		{
			if(playerDeck[sid].activeSlot!=-1)
				return true;
		}
		return false;
	}

	public void CheckCardLocked(int sid, int activeSlot)
	{
		if(!unitActivationInfo.ContainsKey(sid) )
			return;
		if( !playerDeck.ContainsKey(sid) )
			return;
		if( StageManagerWrapper.IsNPCSid(sid) )
			return;
		playerDeck[sid].activeSlot = activeSlot;
		if(activeSlot==-1 && StageManagerWrapper.GetBoardPerson(sid).IsAbnormalState(AbnormalType.SEAL_ACTIVE_CARD_SLOT))
			playerDeck[sid].isCardLocked = true;
		else
			playerDeck[sid].isCardLocked = false;

		if(playerDeck[sid].isCardLocked)
		{
			if( !playerDeck[sid].cardLockEffectCreated)
			{
				playerDeck[sid].cardLockEffectCreated = true;
				//playerDeck[sid].cardLockEffect = NGUITools.AddChild(playerDeck[sid].cardDeck, cardLockPrefab);
				StartCoroutine(CoCardLock(sid));

			}
		}
		else
		{
			if( playerDeck[sid].cardLockEffectCreated)
			{
				playerDeck[sid].cardLockEffectCreated = false;
				//Destroy(playerDeck[sid].cardLockEffect);
				//playerDeck[sid].cardLockEffect = null;
				ReleaseCardLock(sid);
			}
		}
	}

	public bool IsCardLocked(int sid)
	{
		if(!unitActivationInfo.ContainsKey(sid) )
			return false;
		if( !playerDeck.ContainsKey(sid) )
			return false;
		return playerDeck[sid].isCardLocked;
	}

	IEnumerator CoCardLock(int sid)
	{
		if(IsShowDetailDeck(sid))
		{
			foreach(UnitCard card in playerDeck[sid].cards)
			{
				card.CreateCardLock();
				yield return new WaitForSeconds(0.2f);
			}
		}
		else
		{
			if(playerDeck[sid].activeList.Count>0)
			{
				playerDeck[sid].activeList[0].CreateCardLock();
			}
		}
	}

	void ReleaseCardLock(int sid)
	{
		foreach(UnitCard card in playerDeck[sid].cards)
		{
			if(card.lockEffect != null)
			{
				Destroy(card.lockEffect);
				card.lockEffect=null;
			}
		}
	}

	public void ClearUnitActivationInfo(int combatCount, int sid)
	{
		if(!unitActivationInfo.ContainsKey(sid) )
			return;
		unitActivationInfo[sid].Clear(combatCount);
	}
	
	public void AddActivationInfo(int combatCount, int sid, int slot)
	{
		if(!unitActivationInfo.ContainsKey(sid) )
			return;		
		glog.debug("sid="+sid+"  combatCount="+combatCount+"  AddActivationInfo  slot="+slot);
		unitActivationInfo[sid].AddActiveTemp(combatCount, slot);
	}
	
	public void AddDeactivationInfo(int combatCount, int sid, int slot, int remainTurn)
	{
		if(!unitActivationInfo.ContainsKey(sid) )
			return;				
		unitActivationInfo[sid].AddDeactive(combatCount, slot, remainTurn);
	}
	
	public void CheckAddActivationInfo(int combatCount, int sid, bool isNonBattle)
	{
		if(!unitActivationInfo.ContainsKey(sid) )
			return;				
		bool isChanged = unitActivationInfo[sid].CheckDiffActive(combatCount, isNonBattle);
		glog.debug("sid="+sid+"  CheckAddActivationInfo  "+isChanged+ "   combatcount="+combatCount);
	}
	
	public void ClearInfo_NonBattle(int sid)
	{
	
		activeListIndex = 0;
		activeCheckList.Clear();
		deactiveCheckList.Clear();
		shouldMoveToActiveList.Clear();
		if(unitActivationInfo.ContainsKey(sid))
			unitActivationInfo[sid].Clear(0);
	}
	
	public void ClearDeck_BeforeTurnStart(int sid)
	{
		if(!unitActivationInfo.ContainsKey(sid) )
			return;			
		playerDeck[sid].StopGlowFirstActiveCard();
		playerDeck[sid].activeList.Clear();
		playerDeck[sid].deactiveList.Clear();
	}
	
	public void CheckActiveList_BeforeTurnStart(int sid, int slot)
	{
		if(!unitActivationInfo.ContainsKey(sid) )
			return;			
		
		unitActivationInfo[sid].info[0].activeList.Add (slot);
		
		if(IsShowDetailDeck(sid))
		{
			int nPos = unitActivationInfo[sid].info[0].activeList.Count-1;
			foreach( UnitCard card in playerDeck[sid].cards)
			{		
				if(card.slot == slot)
				{
					playerDeck[sid].activeList.Add (card);
					card.SetActivate(true,0);
					card.SetnPos( nPos);
					//iTween.MoveTo( card.gameObject , iTween.Hash("time", 0.1f, "position", cardPos[nPos].localPosition,  "islocal", true, "easetype","easeInSine" )  );
					float moveTime = 0.01f;
					float delayTime = 0.0f;
					if(isAddedTeam)
					{
						moveTime = 0.5f;
						
						if(card.isAddedCard)
						{
							card.gameObject.transform.parent = cardDeck_boss.transform;
							card.isAddedCard = false;
							delayTime = 0.2f;
						}
					}
					MoveToCardPos_Detail(sid,card, moveTime, "easeInSine", delayTime);
					break;
				}
			}
		}
		else
		{
			int activeIndex = unitActivationInfo[sid].info[0].activeList.Count-1;
			foreach( UnitCard card in playerDeck[sid].cards)
			{		
				if(card.slot == slot)
				{
					playerDeck[sid].activeList.Add (card);
					SetOtherPlayerCardPos(sid, activeIndex, card.gameObject);
					card.SetActivate(true,0);
					break;
				}
			}		
			if(activeIndex==0)
				playerDeck[sid].GlowFirstActiveCard();	
		}
	}

	public void CheckDeactiveInfo_BeforeTurnStart(int sid, int slot, int remainTurn)
	{
		if(!unitActivationInfo.ContainsKey(sid) )
			return;		
		
		unitActivationInfo[sid].AddDeactive(0,slot,remainTurn);
		
		if(IsShowDetailDeck(sid))
		{
			int lastActivePos = -1;
			foreach( UnitCard card in playerDeck[sid].activeList)
			{
				lastActivePos++;
			}
				
			int deactivePos = lastActivePos + unitActivationInfo[sid].info[0].deactiveList.Count;
			foreach( UnitCard card in playerDeck[sid].cards)
			{
				if(card.slot == slot)
				{
					playerDeck[sid].deactiveList.Add (card);
					card.SetnPos( deactivePos);
					card.SetActivate(false, remainTurn);
					//iTween.MoveTo( card.gameObject , iTween.Hash("time", 0.1f, "position", cardPos[deactivePos].localPosition,  "islocal", true, "easetype","easeInSine" )  );
					float moveTime = 0.01f;
					if(isAddedTeam)
						moveTime = 0.5f;
					MoveToCardPos_Detail(sid,card, moveTime, "easeInSine", 0);
				}
			}
		}
		else
		{
			foreach( UnitCard card in playerDeck[sid].cards)
			{
				if(card.slot == slot)
				{			
					playerDeck[sid].deactiveList.Add (card);
					SetOtherPlayerCardPos(sid, 1, card.gameObject);
					card.SetActivate(false, remainTurn);
				}
			}
		}
	}
	
	public void Init_ShuffleDeck(int sid)
	{
		if(playerDeck[sid].activeList.Count<=1)
			return;
		
		unitActivationInfo[sid].info[0].activeList.Clear ();
		playerDeck[sid].StopGlowFirstActiveCard();
		
		if(IsShowDetailDeck(sid))
		{
			int a_count = playerDeck[sid].activeList.Count;
			Vector3 midPos = playerDeck[sid].activeList[0].gameObject.transform.localPosition + playerDeck[sid].activeList[a_count-1].gameObject.transform.localPosition;
			midPos = midPos/2;
			if(sid==bossSID)
				midPos.y -= 120;
			else
				midPos.y += 120;
			foreach( UnitCard card in playerDeck[sid].activeList)
			{
				card.SetDisableCardScaleChange(false, 2.0f);

				//iTween.MoveTo( card.gameObject , iTween.Hash("time", 0.5f, "position", midPos,  "islocal", true, "easetype","easeInSine" )  );
				//iTween.ScaleTo( card.gameObject , iTween.Hash("time", 0.5f, "x",1,"y",1 ,"islocal", true, "easetype","easeInSine" )  );

				LeanTween.moveLocal( card.gameObject, midPos, 0.5f).setEase( LeanTweenType.easeInSine );
				LeanTween.scale( card.gameObject, Vector3.one, 0.5f).setEase( LeanTweenType.easeInSine );
			}
		}
		else
		{
			UnitCard curCard = playerDeck[sid].activeList[0];
			//Vector3 destPos = GetOtherPlayerCardPos(sid, "NextCardPos").transform.localPosition;
			//iTween.MoveTo( curcard.gameObject , iTween.Hash("time", 0.5f, "position", destPos,  "islocal", true, "easetype","easeInSine" )  );	
			MoveNextCardPos_OtherPlayer( sid, curCard, 0.5f, "easeInSine");
			StartCoroutine( SetActiveObject(curCard.gameObject, false,0.5f) );
		}
	}
	
	IEnumerator SetActiveObject(GameObject go, bool bActive, float delay)
	{
		yield return new WaitForSeconds(delay);
		go.SetActive(bActive);
	}
	
	public void AddShuffleDeck(int sid, int slot)
	{
		if(playerDeck[sid].activeList.Count<=1)
			return;
		
		unitActivationInfo[sid].info[0].activeList.Add (slot);
	}
	
	public void ShuffleDeck(int sid)
	{
		if(playerDeck[sid].activeList.Count<=1)
			return;
		
		StartCoroutine(CoShuffleDeck(sid));
	}
	
	IEnumerator CoShuffleDeck(int sid)
	{
		glog.debug("COshuffle deck");
		yield return new WaitForSeconds(0.55f);
		
		playerDeck[sid].activeList.Clear();
		
		if(IsShowDetailDeck(sid))
		{
			int index=0;
			foreach( int slot in unitActivationInfo[sid].info[0].activeList)
			{
				glog.debug("COshuffle deck  3");
				int nPos = index;
				float addDelay = 0.0f;
				foreach( UnitCard card in playerDeck[sid].cards)
				{
					if(card.slot == slot)
					{
						playerDeck[sid].activeList.Add (card);
						if(nPos==0)
						{
							playerDeck[sid].GlowFirstActiveCard();
						}
						card.SetnPos( nPos);
						CardMoveNormal(sid,card, 0.3f, addDelay);
						addDelay += 0.1f;
						break;
					}
				}
				index++;
			}
		}
		else
		{
			foreach( int slot in unitActivationInfo[sid].info[0].activeList)
			{
				glog.debug("other player COshuffle deck  3");
				foreach( UnitCard card in playerDeck[sid].cards)
				{
					if(card.slot == slot)
					{
						playerDeck[sid].activeList.Add (card);
						break;
					}
				}
				StartCoroutine( CheckCardMoveDone(playerDeck[sid], sid, null,0));	
			}			
		}
	}
	
	public void Init_CardToTomb(int sid)
	{
		unitActivationInfo[sid].Clear(0);
	}
	
	public void SetActive_CardToTomb(int sid, int slot)
	{
		unitActivationInfo[sid].info[0].activeList.Add (slot);
	}
	
	public void SetDeactive_CardToTomb(int sid, int slot, int remainTurn)
	{
		unitActivationInfo[sid].AddDeactive(0, slot, remainTurn);
	}
	
	public void ActiveCardToTomb(int sid)
	{
		int activeCardCount = playerDeck[sid].activeList.Count;
		if(activeCardCount>0)
		{
			playerDeck[sid].StopGlowFirstActiveCard();
			UnitCard curCard = playerDeck[sid].activeList[0];
			curCard.SetActivate(false, unitActivationInfo[sid].GetRemainTurn(0, curCard.slot) );
			
			if(IsShowDetailDeck(sid)  )
			{
				int lastCardPos = playerDeck[sid].cards.Count - 1;	
				
				Vector3 destPos = Vector3.one;
				Vector3 destScale = Vector3.one;
				float offset_y = 100;
				if(sid==mySID)
				{
					destPos = cardPos[lastCardPos].localPosition;
					destScale = cardPos[lastCardPos].localScale;
				}
				else if(sid==bossSID)
				{
					destPos = bossCardPos[lastCardPos].localPosition;
					destScale = bossCardPos[lastCardPos].localScale;
					offset_y = -offset_y;
				}
				Vector3 midPos1 = (curCard.gameObject.transform.localPosition + destPos)/3.0f;
				midPos1.y += offset_y;
				Vector3 midPos2 = (curCard.gameObject.transform.localPosition + destPos)*2/3.0f;
				midPos2.y += offset_y;
				Vector3 [] pathList = { curCard.gameObject.transform.localPosition, midPos1, midPos2, destPos };				
				curCard.SetnPos(lastCardPos);
				curCard.SetDisableCardScaleChange(false, 0.5f);

				//iTween.MoveTo( curCard.gameObject , iTween.Hash("time", 0.5f, "path", pathList,"movetopath",false,  "islocal", true, "easetype","easeInSine" )  );	
				//iTween.ScaleTo( curCard.gameObject , iTween.Hash("time", 0.5f, "x",destScale.x,"y",destScale.y , "islocal", true, "easetype","easeInSine")  );

				LeanTween.moveLocal( curCard.gameObject, pathList, 0.5f).setEase( LeanTweenType.easeInSine );
				LeanTween.scale( curCard.gameObject, destScale, 0.5f).setEase( LeanTweenType.easeInSine );


				SetCardDepth(curCard.gameObject, curCard.nPos);
				float addDelay = 0.0f;
				foreach(UnitCard card in playerDeck[sid].cards)
				{
					if(card.slot != curCard.slot)
					{
						card.SetnPos(card.nPos-1);
						CardMoveNormal(sid, card, 0.2f, addDelay);
						addDelay += 0.1f;
					}
				}
				ResetDeckActiveList(sid);
				ResetDeckDeactiveList(sid);				
			}
			else
			{
				//Vector3 destPos = GetOtherPlayerCardPos(sid, "NextCardPos").transform.localPosition;
				//iTween.MoveTo( curCard.gameObject , iTween.Hash("time", 0.5f, "position", destPos,  "islocal", true, "easetype","easeInSine" )  );
				MoveNextCardPos_OtherPlayer( sid, curCard, 0.5f, "easeInSine");
				StartCoroutine( SetActiveObject(curCard.gameObject, false,0.5f) );
				ResetDeckActiveList(sid);
				ResetDeckDeactiveList(sid);					
				StartCoroutine( CheckCardMoveDone(playerDeck[sid], sid, null,0));		
			}
			
		}
	}
	
	void SetPositionDeactiveCard_OtherPlayer(int sid, UnitCard card, float time)
	{
		card.SetPositionDeactiveCard_OtherPlayer(sid, time);
	}
	
	public void MoveNextCardPos_OtherPlayer(int sid, UnitCard card, float time, string easeType)
	{
		card.SetForceMovingState(time);
//		Debug.LogError("MoveNextCardPos_OtherPlayer : changed card depth");
		card.ChangeDepth(time, -HudManager.Instance.charSidOrderDic[sid]);
		Vector3 destPos = GetOtherPlayerCardPos(sid, "NextCardPos").transform.localPosition;
		Vector3 destScale = GetOtherPlayerCardPos(sid, "NextCardPos").transform.localScale;
		card.SetDisableCardScaleChange(false, time);
		if(time==0)
		{
			card.gameObject.transform.localPosition = destPos;
			card.gameObject.transform.localScale = destScale;
		}
		else 
		{
			if(IngameSetting.Instance.cardTween == CardTweenType.None)
			{
				card.gameObject.transform.localPosition = destPos;
				card.gameObject.transform.localScale = destScale;
			}
			else// if(IngameSetting.Instance.cardTween == CardTweenType.LeanTween)
			{
				LeanTween.moveLocal(card.gameObject, destPos, time).setEase( strLeanTweenType[easeType]);
				LeanTween.scale( card.gameObject, destScale, time).setEase( strLeanTweenType[easeType]);
			}
			//else
			//{
			//	iTween.MoveTo( card.gameObject , iTween.Hash("time", time, "position",destPos,    "islocal", true, "easetype",easeType )  );
			//	iTween.ScaleTo( card.gameObject , iTween.Hash("time", time, "x",destScale.x,"y",destScale.y , "islocal", true, "easetype",easeType)  );		
			//}
		}
	}
	
	public void CardResurrect(int sid)
	{
		UnitCard resurrectCard = null;
		foreach(UnitCard card in playerDeck[sid].deactiveList)
		{
			foreach( int slot in unitActivationInfo[sid].info[0].activeList)
			{
				if(card.slot == slot)
				{
					resurrectCard = card;
					break;
				}
			}
		}
	}
	
	public void Init_ForceNextCard(int sid)
	{
		unitActivationInfo[sid].info[0].activeList.Clear();
	}
	
	public void Set_ForceNextCard(int sid, int slot)
	{
		unitActivationInfo[sid].info[0].activeList.Add(slot);
	}
	
	public void ForceNextCardActivate(int sid)
	{
		int activeCardCount = playerDeck[sid].activeList.Count;
		if( activeCardCount >=2)
		{
			playerDeck[sid].StopGlowFirstActiveCard();
			if(IsShowDetailDeck(sid))
			{
				int index=0;
				int lastCardPos = playerDeck[sid].activeList[activeCardCount-1].nPos;
				float addDelay = 0.1f;
				foreach(UnitCard card in playerDeck[sid].activeList)
				{
					if(index==0)
					{
						Vector3 destPos = Vector3.one;
						Vector3 destScale = Vector3.one;
						float offset_y = 100;
						if(sid==mySID)
						{
							destPos = cardPos[lastCardPos].localPosition;
							destScale = cardPos[lastCardPos].localScale;
						}
						else if(sid==bossSID)
						{
							destPos = bossCardPos[lastCardPos].localPosition;
							destScale = bossCardPos[lastCardPos].localScale;
							offset_y = -offset_y;
						}
						
						Vector3 midPos1 = (card.gameObject.transform.localPosition + destPos)/3.0f;
						midPos1.y += offset_y;
						Vector3 midPos2 = (card.gameObject.transform.localPosition + destPos)*2/3.0f;
						midPos2.y += offset_y;
						Vector3 [] pathList = { card.gameObject.transform.localPosition, midPos1, midPos2, destPos };
						card.SetnPos(lastCardPos);
						card.SetDisableCardScaleChange(false, 0.7f);


						//iTween.MoveTo( card.gameObject , iTween.Hash("time", 0.7f, "path", pathList,"movetopath",false,  "islocal", true, "easetype","easeInSine" )  );		
						//iTween.ScaleTo( card.gameObject , iTween.Hash("time", 0.7f, "x",destScale.x,"y",destScale.y , "islocal", true, "easetype","easeInSine")  );
						LeanTween.moveLocal( card.gameObject, pathList, 0.7f).setEase( LeanTweenType.easeInSine );
						LeanTween.scale( card.gameObject, destScale, 0.7f).setEase( LeanTweenType.easeInSine );

						//Debug.LogError("ForceNextCardActivate : changed card depth");
						SetCardDepth(card.gameObject, card.nPos);
					}
					else
					{
						card.SetnPos(card.nPos-1);
						CardMoveNormal(sid,card, 0.2f, addDelay);
					}
					addDelay += 0.1f;
					index++;			
				}
				
				ResetDeckActiveList(sid);	
			}
			else
			{
				MoveNextCardPos_OtherPlayer( sid, playerDeck[sid].activeList[0] , 0.5f, "easeInSine");	
				ResetDeckActiveList(sid);
				StartCoroutine( CheckCardMoveDone(playerDeck[sid], sid, null,0));					
			}
			
			bDoneSetUnitActivationInfo_NonBattle=false;
			Invoke("DoneForceNextCard",0.8f);
		}
		
		
	}

	void DoneForceNextCard()
	{
		bDoneSetUnitActivationInfo_NonBattle=true;
	}
	
	void ResetDeckActiveList(int sid)
	{
		playerDeck[sid].activeList.Clear();
		foreach(int slot in unitActivationInfo[sid].info[0].activeList)
		{
			foreach(UnitCard card in playerDeck[sid].cards)
			{
				if(slot == card.slot)
					playerDeck[sid].activeList.Add (card);
			}
		}
		playerDeck[sid].GlowFirstActiveCard();		
	}
	
	void ResetDeckDeactiveList(int sid)
	{
		playerDeck[sid].deactiveList.Clear();
		foreach(int slot in unitActivationInfo[sid].info[0].deactiveList)
		{
			foreach(UnitCard card in playerDeck[sid].cards)
			{
				if(slot == card.slot)
					playerDeck[sid].deactiveList.Add (card);
			}
		}		
	}
	
	void CardMoveNormal(int sid, UnitCard card, float time, float addDelay)
	{
		//iTween.MoveTo( card.gameObject , iTween.Hash("time", time, "delay", addDelay,"position", cardPos[card.nPos].localPosition,  "islocal", true, "easetype","easeOutSine" )  );				
		MoveToCardPos_Detail(sid,card, time, "easeOutSine", addDelay);
	}
	
	public void CheckActiveList_NonBattle(int sid, int slot)
	{
		if(!unitActivationInfo.ContainsKey(sid) )
			return;
		
		unitActivationInfo[sid].AddActiveTemp(0,slot);
		activeCheckList.Add (slot);
		if( activeListIndex >= playerDeck[sid].activeList.Count)
		{
			foreach( UnitCard card in playerDeck[sid].deactiveList)
			{
				if(card.slot == slot)
				{
					shouldMoveToActiveList.Add(card);
					glog.debug("shouldmoveToActive "+card.slot);
					break;
				}
			}
		}
		else
		{
			int curSlot = playerDeck[sid].activeList[activeListIndex].slot;
			if( curSlot != slot)
				Debug.LogError("active list differ  "+ curSlot+"  "+slot);
			
		}
		activeListIndex++;
	}
	
	int LastActivePos(int sid)
	{
		int lastActive = -1;
		foreach( UnitCard card in playerDeck[sid].activeList)
		{
			lastActive++;
		}		
		return lastActive;
	}
	
	public void MoveDeactiveToActive_NonBattle(int sid)
	{
		int lastActive = LastActivePos(sid);
		
		int destPos = lastActive+1;
		foreach( UnitCard card in shouldMoveToActiveList)
		{
			card.SetActivate(true,0);
			if(IsShowDetailDeck(sid))
			{
				if( card.nPos != destPos)
				{
					card.SetnPos(destPos);
					if(IsShowDetailDeck(sid))
					{
						MoveToCardPos_Detail(sid,card, 0.5f, "easeOutSine", 0);
						//iTween.MoveTo( card.gameObject , iTween.Hash("time", 0.5f, "position", cardPos[card.nPos].localPosition, "islocal", true, "easetype","easeOutSine" )  );	
					}
				}
			}
			
			destPos++;
			
		}
		bool isFirstActivated = false;
		foreach(UnitCard card in shouldMoveToActiveList)
		{
			if(playerDeck[sid].activeList.Count==0)
				isFirstActivated = true;
			playerDeck[sid].activeList.Add(card);
			playerDeck[sid].deactiveList.Remove(card);
		}
		
		lastActive = LastActivePos(sid);
		destPos = lastActive+1;
		foreach( UnitCard card in playerDeck[sid].deactiveList)
		{
			if(IsShowDetailDeck(sid))
			{
				if( card.nPos != destPos)
				{
					card.SetnPos(destPos);
					if(IsShowDetailDeck(sid))
					{
						MoveToCardPos_Detail(sid,card, 0.5f, "easeOutSine", 0);
						//iTween.MoveTo( card.gameObject , iTween.Hash("time", 0.5f, "position", cardPos[card.nPos].localPosition, "islocal", true, "easetype","easeOutSine" )  );	
					}
				}
			}
			destPos++;
		}
		
		if(IsShowDetailDeck(sid))
			playerDeck[sid].GlowFirstActiveCard();
		else
		{
			if(isFirstActivated)
			{
				StartCoroutine( CheckCardMoveDone(playerDeck[sid], sid, null,0));
			}
		}
		
	}
	
	public void SetUnitActivationInfo_NonBattle(PC_OP_UNIT_ACTIVATION_INFO packet)
	{
		if( !playerDeck.ContainsKey(packet.ServerID) )
			return;
		glog.debug(" SetUnitActivationInfo_NonBattle  "+bDoneSetUnitActivationInfo_NonBattle);
		StartCoroutine( CoSetUnitActivationInfo_NonBattle(packet) );
	}
	
	IEnumerator CoSetUnitActivationInfo_NonBattle(PC_OP_UNIT_ACTIVATION_INFO packet)
	{
		while(!bDoneSetUnitActivationInfo_NonBattle)
		{
			//glog.debug("wait bDoneSetUnitActivationInfo_NonBattle");
			yield return null;
		}
		bDoneSetUnitActivationInfo_NonBattle = false;
		ClearInfo_NonBattle(packet.ServerID);
		for(int i=0; i< packet.ActiveQueueCount; i++)
		{
			glog.debug(packet.ServerID+"  checkactive "+packet.ActiveQueue[i]);
			CheckActiveList_NonBattle( packet.ServerID, packet.ActiveQueue[i]);
		}
		CheckAddActivationInfo(0, packet.ServerID, true);
		MoveDeactiveToActive_NonBattle( packet.ServerID);
		
		for(int i=0; i< packet.DeactiveCount; i++)
		{
			glog.debug(packet.ServerID+"  -- checkdeactive "+packet.DeactiveList[i]+ "   "+packet.DeactiveTurn[i]);
			CheckDeactiveInfo_NonBattle( packet.ServerID, packet.DeactiveList[i], packet.DeactiveTurn[i]);
		}
		CheckDeactiveInfoFinal_NonBattle(packet.ServerID);	
		yield return new WaitForSeconds(1.0f);
		bDoneSetUnitActivationInfo_NonBattle = true;
	}
	
	public void CheckDeactiveInfo_NonBattle(int sid, int slot, int turn)
	{
		if(!unitActivationInfo.ContainsKey(sid) )
			return;
		
		unitActivationInfo[sid].AddDeactive(0,slot,turn);
		deactiveCheckList.Add(slot);
		
		foreach( UnitCard card in playerDeck[sid].deactiveList)
		{
			if(card.slot == slot )
			{
				glog.debug(sid+"  show decative turn "+slot+"  "+turn);
				card.SetDeactiveRemainTurn(turn);
				return;
			}
		}
		
		Debug.LogError(sid+"  CheckDeactiveInfo not exist  "+slot+"   "+turn);
	}
	
	public void CheckDeactiveInfoFinal_NonBattle(int sid)
	{
		if(!unitActivationInfo.ContainsKey(sid) )
			return;

		bool isMismatch = false;
		if(playerDeck[sid].deactiveList.Count != deactiveCheckList.Count)
		{
			isMismatch = true;
			Debug.LogError("CheckDeactiveInfoFinal  "+playerDeck[sid].deactiveList.Count+ "  "+deactiveCheckList.Count);
		}
		int i=0;
		foreach( UnitCard card in playerDeck[sid].deactiveList)
		{
			bool checkGood = false;
			foreach( int slot in deactiveCheckList)
			{
				if(slot == card.slot)
				{
					checkGood = true;
					glog.debug("deactive checkgood "+slot);
					break;
				}
			}
			
			if(!checkGood)
			{
				isMismatch = true;
				Debug.LogError("deactive list not exist  "+card.slot);
			}
		}
		
		
		
		// check valid active list
		if( unitActivationInfo[sid].CurInfo().activeList.Count != playerDeck[sid].activeList.Count)
		{
			isMismatch = true;
			Debug.LogError(sid+" active list count differ  "+unitActivationInfo[sid].CurInfo().activeList.Count+"  "+playerDeck[sid].activeList.Count);
		}
		i=0;
		foreach( UnitCard card in playerDeck[sid].activeList)
		{
			if( i >= unitActivationInfo[sid].CurInfo().activeList.Count)
				break;

			if(card.slot != unitActivationInfo[sid].CurInfo().activeList[i])
			{
				isMismatch = true;
				Debug.LogError(sid+" slot active differ  "+card.slot+"  "+unitActivationInfo[sid].CurInfo().activeList[i]);
			}
			i++;
		}			

		if(isMismatch)
		{
			RearrangeCards(sid);
		}
	}
	
	
	public void SqueezeMyCardToFront(int sid)
	{
		if(IsShowDetailDeck(sid))
		{
			float addDelay = 0;
			foreach( UnitCard card in playerDeck[sid].activeList)
			{
				if(card.nPos-1>=0)//defense code for card info mismatch
				{
					card.SetnPos(card.nPos-1);
					addDelay += 0.1f;
					MoveToCardPos_Detail(sid,card, 0.4f, "easeOutSine", addDelay);
				}
				//iTween.MoveTo( card.gameObject , iTween.Hash("time", 0.4f,"delay",addDelay, "position", cardPos[card.nPos].localPosition, "islocal", true, "easetype","easeOutSine" )  );	
			}	
		}
	}
	
	public bool PopFirstCard(int sid, int opponentSID, bool isLeftSide, bool isElement, bool isWinner)
	{
		if(!playerDeck.ContainsKey(sid))
			return false;		
		PlayerDeck deck = playerDeck[sid];
		if(deck.activeList.Count==0)
			return false;
		deck.SetCurActiveCard ( deck.activeList[0] );
		deck.curActiveCard.StopGlow();

		if(deck.curActiveCard.isNPCCard)
		{
			deck.curActiveCard.gameObject.SetActive(true);
			deck.curActiveCard.gameObject.transform.localScale = new Vector3(0.2f,0.2f,1);
			deck.curActiveCard.gameObject.transform.localPosition = FindScrPosCenter( StageManagerWrapper.GetBoardPerson(sid).transform.position );
		}
		else
		{

			deck.activeList.RemoveAt(0);
			/*
			 * immediately pop next card 
			if( !IsShowDetailDeck(sid))
			{
				StartCoroutine( CheckCardMoveDone(playerDeck[sid], sid, null,0));
			}*/
		}

		deck.curActiveCard.SetForceMovingState();

		glog.debug(sid+"   PopFirstCard slot="+deck.curActiveCard.slot+"    isLeftside="+isLeftSide);
		
		
		deck.curActiveCard.myParent = deck.curActiveCard.gameObject.transform.parent;
		deck.curActiveCard.gameObject.transform.parent = centerAnchor.transform;
		if(isLeftSide)
			deck.curActiveCard.gameObject.GetComponent<UIPanel>().depth = 24;
		else
			deck.curActiveCard.gameObject.GetComponent<UIPanel>().depth = 25;
		
		Transform destTrans = popPosLeft;
		if(!isLeftSide)
			destTrans = popPosRight;

		deck.curActiveCard.gameObject.transform.localRotation = Quaternion.identity;
		deck.curActiveCard.gameObject.transform.rotation = Quaternion.identity;

		if(deck.curActiveCard.isNPCCard)
		{
			Vector3 midPathVec = (deck.curActiveCard.gameObject.transform.localPosition + destTrans.localPosition)/2 ;
			midPathVec.y += 200;
			Vector3 [] pathList1 = { deck.curActiveCard.gameObject.transform.localPosition, midPathVec, midPathVec, destTrans.localPosition };

			LeanTween.moveLocal( deck.curActiveCard.gameObject, pathList1, popCardTime).setEase(LeanTweenType.easeInSine);
			//iTween.MoveTo( deck.curActiveCard.gameObject , iTween.Hash("time", popCardTime, "path", pathList1,"movetopath",false , "islocal", true, "easetype","easeInSine" )  );
			//LeanTween.rotateAround( deck.curActiveCard.gameObject, new Vector3(0,0,1), 360, popCardTime);
			//deck.curActiveCard.RotatePopup(popCardTime);
			iTween.ScaleTo( deck.curActiveCard.gameObject , iTween.Hash("time", popCardTime, "x", destTrans.localScale.x, "y", destTrans.localScale.y, "islocal", true, "easetype","easeInSine" )  );
		}
		else
		{
			//iTween.MoveTo( deck.curActiveCard.gameObject , iTween.Hash("time", popCardTime, "position", destTrans.localPosition , "islocal", true, "easetype","easeInSine" )  );
			LeanTween.moveLocal( deck.curActiveCard.gameObject, destTrans.localPosition, popCardTime).setEase(LeanTweenType.easeInSine);
			//LeanTween.rotateAround( deck.curActiveCard.gameObject, new Vector3(0,0,1), 360, popCardTime);
			//deck.curActiveCard.RotatePopup(popCardTime);
			iTween.ScaleTo( deck.curActiveCard.gameObject , iTween.Hash("time", popCardTime, "x", destTrans.localScale.x, "y", destTrans.localScale.y, "islocal", true, "easetype","easeInSine" )  );
		}
		//iTween.PunchPosition( deck.curActiveCard.gameObject , iTween.Hash("time", 0.1f, "delay",popCardTime,"x",5,"y",5 ,"space","self")  );
		iTween.PunchScale( deck.curActiveCard.gameObject , iTween.Hash("time", 0.05f, "delay",popCardTime+0.02f,"x",0.5f,"y",0.5f )  );
		if(isElement)
		{
			deck.curActiveCard.PlayElementFX(opponentSID, popCardTime, isWinner);
			return true;
		}
		
		return false;
		
		/*
		if( IsShowDetailDeck(sid))
		{
			Vector3 destPos = FindScrPos(isLeftSide, sid, deck.anchor);
			destPos.z = deck.curActiveCard.gameObject.transform.localPosition.z - 0.1f;
			//Vector3 [] pathList = { deck.curActiveCard.gameObject.transform.localPosition, moveMidPoint.localPosition, destPos };
			//iTween.MoveTo( deck.curActiveCard.gameObject , iTween.Hash("time", 0.5f, "path", pathList,"movetopath",false,  "islocal", true, "easetype","easeInSine" )  );
			iTween.MoveTo( deck.curActiveCard.gameObject , iTween.Hash("time", 0.5f, "position", destPos , "islocal", true, "easetype","easeInSine" )  );
			if(sid==bossSID)
			{
				float sizeMod = 1.2f * ( 0.25f/0.2f);
				iTween.ScaleTo( deck.curActiveCard.gameObject , iTween.Hash("time", 0.5f, "x", sizeMod, "y", sizeMod, "islocal", true, "easetype","easeInSine" )  );
			}
			else
				iTween.ScaleTo( deck.curActiveCard.gameObject , iTween.Hash("time", 0.5f, "x", 1.2f, "y", 1.2f, "islocal", true, "easetype","easeInSine" )  );
//			float addDelay = 0;
//			foreach( UnitCard card in deck.activeList)
//			{
//				card.nPos--;
//				addDelay += 0.1f;
//				iTween.MoveTo( card.gameObject , iTween.Hash("time", 0.5f,"delay",0.4f + addDelay, "position", cardPos[card.nPos].localPosition, "islocal", true, "easetype","easeOutSine" )  );	
//			}
		}
		else
		{
			//Vector3 destPos = FindScrPos(isLeftSide, HudManager.Instance.charPanelScaleMod, deck.anchor);
			Vector3 destPos = FindScrPos(isLeftSide, sid, deck.anchor);
			destPos.z = deck.curActiveCard.gameObject.transform.localPosition.z;
			iTween.MoveTo( deck.curActiveCard.gameObject , iTween.Hash("time", 0.5f, "position", destPos , "islocal", true, "easetype","easeInSine" )  );
			float scaleMod = HudManager.Instance.charPanelScaleMod;
			//iTween.ScaleBy( deck.curActiveCard.gameObject , iTween.Hash("time", 0.5f, "amount", new Vector3(scaleMod,scaleMod,1.0f) , "islocal", true, "easetype","easeInSine" )  );
			float sizeMod = 1.2f * ( 0.25f/0.24f);
			iTween.ScaleTo( deck.curActiveCard.gameObject , iTween.Hash("time", 0.5f, "x", sizeMod, "y", sizeMod, "islocal", true, "easetype","easeInSine" )  );
//			if(deck.activeList.Count>0)
//			{
//				UnitCard nextCard = deck.activeList[0];
//				nextCard.gameObject.SetActive(true);
//				destPos = GetOtherPlayerCardPos(sid, "CardPos").transform.localPosition;
//				iTween.MoveTo( nextCard.gameObject , iTween.Hash("time", 0.5f,"delay",0.3f, "position", destPos, "islocal", true, "easetype","easeOutSine" )  );	
//			}
		}*/
	}

	IEnumerator CoNPCCardRepositionDone(GameObject go, float delay)
	{
		yield return new WaitForSeconds(delay);
		go.SetActive(false);
	}

	public void PushToActiveQueue(int sid)
	{
		if(!playerDeck.ContainsKey(sid))
			return;		
		PlayerDeck deck = playerDeck[sid];
		if(deck.curActiveCard==null)
			return;
		deck.curActiveCard.RemoveElementLoseDimmed();
		if(deck.curActiveCard.isNPCCard)
		{
			/*
			Vector3 returnPos = FindScrPosCenter( StageManagerWrapper.GetBoardPerson(sid).transform.position );
			iTween.ScaleTo( deck.curActiveCard.gameObject , iTween.Hash("time", 0.4f, "x",0.2f,"y",0.2f , "islocal", true, "easetype","easeOutSine" )  );

			Vector3 midPathVec = returnPos;
			midPathVec.y += 200;
			Vector3 [] pathList1 = { deck.curActiveCard.gameObject.transform.localPosition, midPathVec, returnPos };
			iTween.MoveTo( deck.curActiveCard.gameObject , iTween.Hash("time", 0.4f, "path", pathList1,"movetopath",false , "islocal", true, "easetype","easeOutSine" )  );
			//iTween.MoveTo( deck.curActiveCard.gameObject , iTween.Hash("time", 0.5f, "position", returnPos,  "islocal", true, "easetype","easeInSine" )  );
			StartCoroutine( CoNPCCardRepositionDone(deck.curActiveCard.gameObject, 0.4f) ); */
			deck.curActiveCard.gameObject.SetActive(false);
			deck.curActiveCard.SetStillState();
			return;
		}

		deck.curActiveCard.gameObject.SetActive(true);

		deck.curActiveCard.gameObject.transform.parent = deck.curActiveCard.myParent;
		
		if( IsShowDetailDeck(sid) )
		{
			int lastCardPos = -1;
			foreach( UnitCard card in deck.activeList)
			{
				lastCardPos = card.nPos;
			}		
			deck.curActiveCard.SetnPos( lastCardPos+1);
			//iTween.MoveTo( deck.curActiveCard.gameObject , iTween.Hash("time", 0.5f, "position", cardPos[deck.curActiveCard.nPos].localPosition,  "islocal", true, "easetype","easeInSine" )  );
			MoveToCardPos_Detail(sid, deck.curActiveCard, 0.5f, "easeInSine", 0);
		}
		else
		{
			//Vector3 destPos = GetOtherPlayerCardPos(sid, "NextCardPos").transform.localPosition;
			//iTween.MoveTo( deck.curActiveCard.gameObject , iTween.Hash("time", 0.5f, "position", destPos,  "islocal", true, "easetype","easeInSine" )  );
			//float scaleMod = 1/HudManager.Instance.charPanelScaleMod;
			//iTween.ScaleBy( deck.curActiveCard.gameObject , iTween.Hash("time", 0.5f, "amount", new Vector3(scaleMod,scaleMod,1) , "islocal", true, "easetype","easeInSine" )  );
			//iTween.ScaleTo( deck.curActiveCard.gameObject , iTween.Hash("time", 0.5f, "x",1,"y",1 , "islocal", true, "easetype","easeInSine" )  );
			deck.curActiveCard.SetnPos(1);
			MoveNextCardPos_OtherPlayer( sid, deck.curActiveCard, 0.5f, "easeInSine");
			StartCoroutine( CheckCardMoveDone(deck, sid, deck.curActiveCard.gameObject, 0.5f));

		}
		
		deck.activeList.Add( deck.curActiveCard);	
		deck.ClearCurActiveCard();
	}
	
	public void PushToDeactiveList(int sid)
	{
		if(!playerDeck.ContainsKey(sid))
			return;		
		PlayerDeck deck = playerDeck[sid];
		if(deck.curActiveCard==null)
			return;
		
		//deck.curActiveCard.SetActivate(false);
		deck.curActiveCard.RemoveElementLoseDimmed();
		if(deck.curActiveCard.isNPCCard)
		{
			//Destroy(deck.curActiveCard.gameObject);
			//Debug.LogError("NPCCard  PushToDeactiveList  "+deck.curActiveCard.SID);
			deck.curActiveCard.gameObject.SetActive(false);// in case coma skill, dont destroy. 
			deck.curActiveCard.SetStillState();
			return;
		}
		
		deck.curActiveCard.gameObject.transform.parent = deck.curActiveCard.myParent;
		
		if( IsShowDetailDeck(sid) )
		{
			glog.debug("pushToDeactive  deck.curActiveCard="+deck.curActiveCard.slot);
			int lastCardPos = deck.cards.Count - 1;
			glog.debug("pushToDeactive   lastCardPos="+lastCardPos);
			float addDelay = 0;
			foreach( UnitCard card in deck.deactiveList)
			{
				//lastCardPos = card.nPos;
				card.SetnPos(  card.nPos-1);
				addDelay += 0.1f;
				//iTween.MoveTo( card.gameObject , iTween.Hash("time", 0.5f,"delay",addDelay, "position", cardPos[card.nPos].localPosition, "islocal", true, "easetype","easeOutSine" )  );	
				MoveToCardPos_Detail(sid, card, 0.5f, "easeOutSine", addDelay);
			}		
			deck.curActiveCard.SetnPos(lastCardPos);
			SetPositionDeactiveCard(sid, deck.curActiveCard);
			MoveToCardPos_Detail(sid, deck.curActiveCard, 0.5f, "easeOutBounce", 0.3f);
			//iTween.MoveTo( deck.curActiveCard.gameObject , iTween.Hash("time", 0.5f,"delay",addDelay, "position", cardPos[deck.curActiveCard.nPos].localPosition,  "islocal", true, "easetype","easeInSine" )  );
		}
		else
		{
			//Vector3 destPos = GetOtherPlayerCardPos(sid, "NextCardPos").transform.localPosition;
			//Vector3 destScale = GetOtherPlayerCardPos(sid, "NextCardPos").transform.localScale;
			//iTween.MoveTo( deck.curActiveCard.gameObject , iTween.Hash("time", 0.5f, "position", destPos,  "islocal", true, "easetype","easeInSine" )  );
			//float scaleMod = 1/HudManager.Instance.charPanelScaleMod;
			//iTween.ScaleBy( deck.curActiveCard.gameObject , iTween.Hash("time", 0.5f, "amount", new Vector3(scaleMod,scaleMod,1) , "islocal", true, "easetype","easeInSine" )  );
			//iTween.ScaleTo( deck.curActiveCard.gameObject , iTween.Hash("time", 0.5f, "x",destScale.x, "y",destScale.y , "islocal", true, "easetype","easeInSine" )  );
			SetPositionDeactiveCard_OtherPlayer(sid, deck.curActiveCard, 0.5f);
			//MoveNextCardPos_OtherPlayer( sid, deck.curActiveCard, 0.5f, "easeInSine");			
			StartCoroutine( CheckCardMoveDone(deck,sid, null, 0));			
		}
		
		
		deck.deactiveList.Add( deck.curActiveCard);
		deck.ClearCurActiveCard();
	}	
	
	void SetPositionDeactiveCard(int sid, UnitCard card)
	{
		if(sid==mySID)
		{
			Vector3 newPos = cardPos[card.nPos].localPosition;
			newPos.y -= 385;
			card.gameObject.transform.localPosition = newPos;
			card.gameObject.transform.localScale = cardPos[card.nPos].localScale;
		}
		else if(sid==bossSID)
		{
			Vector3 newPos = bossCardPos[card.nPos].localPosition;
			newPos.y += 385;
			card.gameObject.transform.localPosition = newPos;
			card.gameObject.transform.localScale = bossCardPos[card.nPos].localScale;			
		}
		
		card.gameObject.SetActive(true);
		card.SetActivate(false, unitActivationInfo[sid].GetDeactiveRemainTurn(card.slot) );
	}
	
	void MoveToCardPos_Detail(int sid, UnitCard card, float time, string easeType, float addDelay)
	{
		card.SetForceMovingState(time + addDelay);
		//Debug.LogError("MoveToCardPos_Detail : changed card depth");
		card.SetDisableCardScaleChange(false, time+addDelay );
		card.ChangeDepth(time, card.nPos);
		//SetCardDepth(card.gameObject, card.nPos);
		if(sid==mySID)
		{
			if(card.nPos>=cardPos.Length || card.nPos==-1)
			{
				Debug.LogError("card nPos "+card.nPos);
			}
			float x = cardPos[card.nPos].localScale.x;
			float y = cardPos[card.nPos].localScale.y;
			if(time == 0 && addDelay==0)
			{
				card.gameObject.transform.localPosition = cardPos[card.nPos].localPosition;
				card.gameObject.transform.localScale = cardPos[card.nPos].localScale;
			}
			else// if(IngameSetting.Instance.cardTween == CardTweenType.LeanTween)
			{
				LeanTween.moveLocal( card.gameObject, cardPos[card.nPos].localPosition, time).setDelay(addDelay).setEase( strLeanTweenType[easeType] );
				LeanTween.scale( card.gameObject, cardPos[card.nPos].localScale, time).setDelay(addDelay).setEase( strLeanTweenType[easeType] );
			}
			//else
			//{
			//	iTween.MoveTo( card.gameObject , iTween.Hash("time", time, "position",cardPos[card.nPos].localPosition, "delay",addDelay,   "islocal", true, "easetype",easeType )  );
			//	iTween.ScaleTo( card.gameObject , iTween.Hash("time", time, "x",x,"y",y ,"delay",addDelay, "islocal", true, "easetype",easeType)  );
			//}
		}
		else if(sid==bossSID)
		{
			float x = bossCardPos[card.nPos].localScale.x;
			float y = bossCardPos[card.nPos].localScale.y;
			iTween.MoveTo( card.gameObject , iTween.Hash("time", time, "position",bossCardPos[card.nPos].localPosition, "delay",addDelay,   "islocal", true, "easetype",easeType )  );
			iTween.ScaleTo( card.gameObject , iTween.Hash("time", time, "x",x,"y",y ,"delay",addDelay, "islocal", true, "easetype",easeType)  );
		}
	}

	IEnumerator CheckPopupCardMoveDone(PlayerDeck deck, int sid, GameObject go, float delay)
	{
		if(go!=null)
		{
			bCheckOtherPlayerCardMoveDone = true;
			yield return new WaitForSeconds(delay);
			//			BoardManager.Instance.StopFSM(go, "deactive");
			//go.transform.localScale = new Vector3(1,1,1);
			go.SetActive(false);
			
			yield return new WaitForSeconds(0.3f);
		}

		bCheckOtherPlayerCardMoveDone = false;
	}

	IEnumerator CheckCardMoveDone(PlayerDeck deck, int sid, GameObject go, float delay)
	{
		if(go!=null)
		{
			bCheckOtherPlayerCardMoveDone = true;
			yield return new WaitForSeconds(delay);
//			BoardManager.Instance.StopFSM(go, "deactive");
			//go.transform.localScale = new Vector3(1,1,1);
			go.SetActive(false);
			
			yield return new WaitForSeconds(0.3f);
		}
		
		if(deck.activeList.Count>0)
		{
			glog.debug(" other player next card slide");
			UnitCard nextCard = deck.activeList[0];
			nextCard.gameObject.SetActive(true);
			nextCard.nPos = 0;
			//nextCard.gameObject.transform.localScale = Vector3.one;

			Vector3 destPos = GetOtherPlayerCardPos(sid, "CardPos").transform.localPosition;
			Vector3 destScale = GetOtherPlayerCardPos(sid, "CardPos").transform.localScale;
			float timeChange = 0.3f;
			float timeDelay = 0.2f;
			nextCard.SetForceMovingState(timeChange + timeDelay);
			nextCard.SetDisableCardScaleChange(false, timeChange + timeDelay + 0.1f);

			if(IngameSetting.Instance.cardTween == CardTweenType.None)
			{
				nextCard.gameObject.transform.localPosition = destPos;
				nextCard.gameObject.transform.localScale = destScale;
			}
			else //if(IngameSetting.Instance.cardTween == CardTweenType.LeanTween)
			{
				LeanTween.moveLocal( nextCard.gameObject, destPos, timeChange).setDelay(timeDelay).setEase( strLeanTweenType["easeOutSine"]);
				LeanTween.scale( nextCard.gameObject, destScale, timeChange).setDelay(timeDelay).setEase( strLeanTweenType["easeOutSine"]);
			}
			//else
			//{
			//	iTween.MoveTo( nextCard.gameObject , iTween.Hash("time", timeChange,"delay",timeDelay, "position", destPos, "islocal", true, "easetype","easeOutSine" )  );
			//	iTween.ScaleTo( nextCard.gameObject , iTween.Hash("time", timeChange,"delay",timeDelay, "x",destScale.x, "y",destScale.y , "islocal", true, "easetype","easeOutSine" )  );
			//}
			yield return new WaitForSeconds(0.5f);
			deck.GlowFirstActiveCard();

			bCheckOtherPlayerCardMoveDone = false;
		}
		else
			bCheckOtherPlayerCardMoveDone = false;
	}
	

	
	public Vector3 GetCardOriginalPos(UnitCard card)
	{
		if(card.SID==mySID )
		{
			return cardPos[card.nPos].localPosition;
		}
		else if(card.SID == bossSID)
		{
			return bossCardPos[card.nPos].localPosition;
		}
		else
		{
			return GetOtherPlayerCardPos(card.SID, "CardPos").transform.localPosition;
		}
	}
	
	public Vector3 GetCardOriginalScale(UnitCard card)
	{
		if(card.SID==mySID )
		{
			return cardPos[card.nPos].localScale;
		}
		else if(card.SID == bossSID)
		{
			return bossCardPos[card.nPos].localScale;
		}
		else
		{
			return GetOtherPlayerCardPos(card.SID, "CardPos").transform.localScale;
		}
	}
	
	public bool IsShowDetailDeck(int sid)
	{
		if(sid==mySID || sid == bossSID)
			return true;
		return false;
	}
	
//	bool IsUnitCardActivateChanged(int sid)
//	{
//		return unitActivationInfo[sid].CurCombatInfo().isChanged;
//		
		//glog.debug(sid+"  IsUnitCardActivateChanged  "+unitActivationInfo[sid].activeList.Count+"   "+deck.activeList.Count);
		//일단 있기만 하면 true
//		if(deck.activeList.Count>0)
//			return true;
//		
//		return false;

//	}
	
//	public bool IsChangedCardNextBattle(int winnerSID, int loserSID)
//	{
//		if( unitActivationInfo[winnerSID].NextCombatInfo().isChanged || unitActivationInfo[loserSID].NextCombatInfo().isChanged)
//			return true;
//		return false;
//	}
	
	bool ShouldPopCard(int sid, PlayerDeck deck)
	{
		if( unitActivationInfo[sid].CurCombatInfo().activeList.Count == 0 && deck.activeList.Count >0 )
			return true;
		
		if( unitActivationInfo[sid].CurCombatInfo().activeList.Count >0 && deck.activeList.Count >0
				&& unitActivationInfo[sid].CurCombatInfo().activeList[0] != deck.activeList[0].slot )
			return true;
		return false;
	}

	public void RematchEffect()
	{
		SoundManager.Instance.PlaySound(38);
		UIManager.Instance.CardSkillNameShow( UIType.UI_COMBAT_REMATCH );
	}

	public void RediceEffect()
	{
		UIManager.Instance.CardSkillNameShow(UIType.UI_COMBAT_REDICE);
	}
	
	public bool CardBattleStart(BoardPerson person, BoardPerson opponent,  bool isElement, bool isElementWin)
	{
		maxCombatCount = BattleManager.Instance.maxCombatCount;
		int sid = person.SID;
		if(!playerDeck.ContainsKey(sid))
			return false;				
//		Vector3 pos = Vector3.zero;
//
//		float offsetX = 0.54f;
//		float offsetY = 0.36f;
//		if( BattleManager.Instance.IsPersonLeftSide(person) )
//			offsetX = -offsetX;
//		pos = person.transform.position;
	//	pos.x += offsetX;
	//	pos.y += offsetY;
		PlayerDeck deck = playerDeck[sid];
		glog.debug(sid+" CardBattleStart  "+isElementWin, LOGCOLOR.YELLOW);
		//glog.debug("curactivecard set null "+person.SID);
		//deck.isUnitCardActivateChanged = unitActivationInfo[person.SID].CurCombatInfo().isChanged;
		//if( deck.isUnitCardActivateChanged)
		bool shouldPopCard = false;
		if(battleManagerCombatCount==1)
		{
			//if(BattleManager.Instance.isRematchBattleDoing)
			//{
			//	RematchEffect();
			//}
			shouldPopCard = true;
			if(BattleManager.Instance.isRediceBattleDoing)
			{
				shouldPopCard = false;
			}
			if(deck.curActiveCard!=null)
			{
				shouldPopCard = false;
				if( deck.curActiveCard.isNPCCard && !deck.curActiveCard.gameObject.activeSelf)
					shouldPopCard = true;
				if(BattleManager.Instance.isRematchBattleDoing)
				{
					if(!shouldPopCard)
					{
						if(isElement)
						{
							glog.debug("rematch already poped card play element fx");
							deck.curActiveCard.PlayElementFX(opponent.SID, popCardTime, isElementWin);
						}
					}
				}
			}
		}
		else
		{

			/* when rematch , battleManagerCombatCount is 1 too
			if( deck.curActiveCard == null)           //ShouldPopCard(sid, deck) )
			{
				//ShowSkillNameEffect("rematch");
				RematchEffect();
				shouldPopCard = true;
			}
			else
			{
				if(isElement)
				{   
					// for rematch
					glog.debug("for rematch playElementFX  "+opponent.SID);
					deck.curActiveCard.PlayElementFX(opponent.SID, popCardTime, isElementWin);
					return true;
				}				
			}*/
		}

		if( deck.isCardLocked)
			shouldPopCard = false;

		if(shouldPopCard)
			return PopFirstCard(sid, opponent.SID , ShouldPopLeftSide(person, opponent) ,isElement ,isElementWin );
		
		return false;
	}
	
	bool ShouldPopLeftSide(BoardPerson person, BoardPerson opponent)
	{
//		if(person.order == 1)
//			return true;
//		else if(person.order == 4)
//			return false;
//		else if(person.order == 2 )
//		{
//			if(opponent.order == 1)
//				return false;
//			else
//				return true;
//		}
//		else if(person.order == 3)
//		{
//			if(opponent.order == 4)
//				return true;
//			else
//				return false;
//		}
//		else
//			return true;
		
		if( BattleManager.Instance.IsPersonLeftSide(person) )
			return true;
		return false;
		
	}
	
	public bool HasCurActiveCard(int sid)
	{
		if(!playerDeck.ContainsKey(sid))
			return false;
		if( playerDeck[sid].curActiveCard == null)
			return false;
		return true;
	}

	public UnitCard CurActiveCard(int sid)
	{
		return playerDeck[sid].curActiveCard;
	}
	
	public void BattleEnd(int winnerSID, int loserSID, bool isFinal)
	{
		glog.debug(isCoBattleEndRunning+" ========= BattleEnd ======== "+isFinal);
		isCoBattleEndRunning = true;
		StartCoroutine( CoBattleEnd(winnerSID, loserSID, isFinal) );
	}
	
	void DeactivateEffectShow(int sid, UnitCard card, bool isGoDeactive)
	{
//		BoardManager.Instance.RestartFSM(card.gameObject, "deactive");
//		GameObject goEff = EffectManager.Instance.NGUICreateEffect(2, card.gameObject);
//		Quaternion newRot = HudManager.Instance.GetCharPanel(sid).transform.localRotation;
//		goEff.transform.localRotation = newRot;
//		Destroy(goEff,2.0f);
		
		card.ShowCardDestrory();
		
//		if(isGoDeactive)
//			card.SetActivate(false, unitActivationInfo[sid].GetDeactiveRemainTurn(card.slot));
	}
	
	public void ShowSkillNameEffect(string skillName)
	{
		glog.debug("-- Skill Name Show  "+skillName);
		if( skillNameShowGo1.activeSelf)
			skillNameShowGo = skillNameShowGo2;
		else
			skillNameShowGo = skillNameShowGo1;
		//GameObject go = NGUITools.AddChild( centerAnchor, skillNameShowPrefab);
		skillNameShowGo.transform.localScale = skillNameShowPrefab.transform.localScale;
		skillNameShowGo.transform.localPosition = skillNameShowPrefab.transform.localPosition;
		skillNameShowGo.SetActive(true);
		//BoardManager.Instance.RestartFSM( skillNameShowGo.GetComponent<PlayMakerFSM>() );
		skillNameShowGo.GetComponent<UILabel>().text = skillName;
		//Destroy(go,1.0f);		
	}
	
	public void ShowSkillNameEffect(string skillName, Transform trans)
	{
		glog.debug("-- ingame text Name Show  "+skillName);
		Vector3 pos = trans.position;
		pos.z = ingameTextShowPrefab.transform.position.z;
		if( ingameTextShowGo1.activeSelf)
			ingameTextShowGo = ingameTextShowGo2;
		else
			ingameTextShowGo = ingameTextShowGo1;		
		//GameObject go = Instantiate( ingameTextShowPrefab, pos, Quaternion.identity) as GameObject;
		ingameTextShowGo.transform.position = pos;
		ingameTextShowGo.SetActive(true);
		//BoardManager.Instance.RestartFSM( ingameTextShowGo.GetComponent<PlayMakerFSM>() );
		ingameTextShowGo.transform.parent = trans;
		ingameTextShowGo.GetComponent<UILabel>().text = skillName;
	
	}	
	
	public void WinnerCardAttack(int winnerSID, BoardPerson person, int loserSID)
	{
		PlayerDeck winnerDeck = null;
		if( playerDeck.ContainsKey(winnerSID) )
			winnerDeck = playerDeck[winnerSID];	
		PlayerDeck loserDeck = null;
		if( playerDeck.ContainsKey(loserSID) )
			loserDeck = playerDeck[loserSID];		
		
		if(loserDeck != null && loserDeck.curActiveCard != null)
		{
			if(winnerDeck!=null && winnerDeck.curActiveCard!=null)
			{
				//winnerDeck.curActiveCard.cardAttackScript.isRightSide = false;
				//if( !BattleManager.Instance.IsPersonLeftSide(person) )
				//	winnerDeck.curActiveCard.cardAttackScript.isRightSide = true;
				//if(winnerDeck.IsMirrorSide() )
				//	winnerDeck.curActiveCard.cardAttackScript.isRightSide = !winnerDeck.curActiveCard.cardAttackScript.isRightSide;
				
				//bool bScaleback = false;
				//if(IsPlayerDeck(winnerDeck) )
				//	bScaleback = true;
				//winnerDeck.curActiveCard.cardAttackScript.SetActivate(bScaleback);
				
			}
		}
	}
	
	bool IsPlayerDeck(PlayerDeck deck)
	{
		if(deck == myDeck)
			return true;
		return false;
	}
	
	IEnumerator CoBattleEnd(int winnerSID, int loserSID, bool isFinal)
	{
		isCardWinAndBreakDone = false;
		glog.debug(" ========= BattleEnd 2======== "+isFinal);
		PlayerDeck loserDeck = null;
		if( playerDeck.ContainsKey(loserSID) )
			loserDeck = playerDeck[loserSID];
		PlayerDeck winnerDeck = null;
		if( playerDeck.ContainsKey(winnerSID) )
			winnerDeck = playerDeck[winnerSID];
		
		bool isWinnerDestroyed = false;
		bool isLoserDestroyed = false;
		bool isWinnerWinEffected = false;
		
		Vector3 winnerCardPos = Vector3.zero;
		Vector3 winnerCardScale = Vector3.zero;
		Vector3 loserCardPos = Vector3.zero;
		Vector3 loserCardScale = Vector3.zero;
		
		if(loserDeck != null && loserDeck.curActiveCard != null)
		{
			glog.debug(" ========= BattleEnd 3======== ");
			
			if(winnerDeck != null && winnerDeck.curActiveCard != null)
			{
				if( unitActivationInfo[winnerSID].CurCombatInfo().deactiveList.Contains(winnerDeck.curActiveCard.slot) )
				{
					isWinnerDestroyed = true;
					
					winnerCardPos = winnerDeck.curActiveCard.transform.localPosition;
					winnerCardScale = winnerDeck.curActiveCard.transform.localScale;
					
					DeactivateEffectShow( winnerSID, winnerDeck.curActiveCard, true);
					//ShowSkillNameEffect("coma");
					//UIManager.Instance.CardSkillNameShow(UIType.UI_COMBAT_COMA);
					UIManager.Instance.CardSkillNameShow(CStringTableManager.Instance.GetItemById(2415));

					ShowPopupCardSkillEffect(loserSID);
					//ShowSkillNameEffect(CStringTableManager.Instance.GetItemById(1688));
				}
				else
				{
				//	winnerDeck.curActiveCard.cardAttackScript.bActivate = true;
				//	while(!winnerDeck.curActiveCard.cardAttackScript.bAttackEventTriggered)
				//	{
				//		yield return null;
				//	}
				}
			}
			

			isLoserDestroyed = true;
			
//			yield return new WaitForSeconds(0.3f);
		}
		
		
		
		bool shouldWinnerMove = false;
		
		if(winnerDeck != null && winnerDeck.curActiveCard != null)
		{
			
			if(isFinal)
				shouldWinnerMove = true;
			else
			{
				if( unitActivationInfo[winnerSID].IsCurCombatCardChanged())
				{
					shouldWinnerMove = true;
				}
			}
			if(!isWinnerDestroyed)
			{
				winnerDeck.curActiveCard.ShowWinEffect();
				isWinnerWinEffected = true;
			}

		}

		if(BattleManager.Instance.isRematch)
			shouldWinnerMove = false;
		
		bool shouldLoserMove = false;
		
		if(loserDeck != null && loserDeck.curActiveCard != null )
		{
			glog.debug(" ========= BattleEnd 7======== ");
			
			if(isFinal)
				shouldLoserMove = true;
			else
			{
				if( unitActivationInfo[loserSID].IsCurCombatCardChanged())
				{
					shouldLoserMove = true;
				}
			}
			if(isLoserDestroyed)
			{
				if(isWinnerWinEffected)
					yield return new WaitForSeconds(0.5f);
					
				bool isGoDeactive = false;
				if( unitActivationInfo[loserSID].CurCombatInfo().deactiveList.Contains(loserDeck.curActiveCard.slot) )
					isGoDeactive = true;
				
				loserCardPos = loserDeck.curActiveCard.transform.localPosition;
				loserCardScale = loserDeck.curActiveCard.transform.localScale;	
				
				DeactivateEffectShow( loserSID, loserDeck.curActiveCard, isGoDeactive);
			}
		}		
		
		
		if(isLoserDestroyed || isWinnerWinEffected)
			yield return new WaitForSeconds(1.5f);
		
		if(BattleManager.Instance.isRedice)
		{
			shouldLoserMove = false;
		}

		if(shouldLoserMove)
		{
			glog.debug(loserSID+"  shouldLoserMove "+loserDeck.curActiveCard.slot);
			SqueezeMyCardToFront(loserSID);
			if( unitActivationInfo[loserSID].CurCombatInfo().deactiveList.Contains(loserDeck.curActiveCard.slot) )
				PushToDeactiveList(loserSID);
			else
				PushToActiveQueue(loserSID);
//				yield return new WaitForSeconds(0.2f);
		}		

		if(shouldWinnerMove)
		{			
			SqueezeMyCardToFront(winnerSID);
			if( unitActivationInfo[winnerSID].CurCombatInfo().deactiveList.Contains(winnerDeck.curActiveCard.slot) )
				PushToDeactiveList(winnerSID);
			else
				PushToActiveQueue(winnerSID);
//				yield return new WaitForSeconds(0.2f);
		}
		
		
		
		if(!shouldLoserMove && !shouldWinnerMove && !isFinal)
		{
			if(isWinnerDestroyed)
			{
				winnerDeck.curActiveCard.gameObject.SetActive(true);
				winnerDeck.curActiveCard.gameObject.transform.localPosition = winnerCardPos;
				winnerDeck.curActiveCard.gameObject.transform.localScale = winnerCardScale;
				
			}
			if(isLoserDestroyed)
			{
				loserDeck.curActiveCard.gameObject.SetActive(true);
				CardSkillEffect( loserDeck.curActiveCard);// card skill effect for redice
				loserDeck.curActiveCard.gameObject.transform.localPosition = loserCardPos;
				loserDeck.curActiveCard.gameObject.transform.localScale = loserCardScale;
			}
				
			//ShowSkillNameEffect("redice");
			//UIManager.Instance.CardSkillNameShow(UIType.UI_COMBAT_REDICE);
		}
		
		if(isFinal)
		{
			maxCombatCount = 0;
			isCardWinAndBreakDone = true;
		}
		
		yield return new WaitForSeconds(0.1f);
		
//		if(isFinal)
//		{
//			CompareFinalList(winnerSID);
//			CompareFinalList(loserSID);
//			
//			BattleManager.Instance.maxCombatCount = 0;
//			BattleManager.Instance.combatCount = 0;						
//		}
		
		yield return new WaitForSeconds(0.3f);
		
		if(winnerDeck != null && winnerSID == mySID)
			winnerDeck.GlowFirstActiveCard();
		if(loserDeck != null && loserSID == mySID)
			loserDeck.GlowFirstActiveCard();		
		
		isCoBattleEndRunning = false;
		
		if(isFinal)
		{
			SetEnableAllCardScaleChange(winnerSID, true);
			SetEnableAllCardScaleChange(loserSID, true);	
			
			if( winnerSID == mySID || loserSID == mySID)
			{
				yield return new WaitForSeconds(0.5f);
				ShowActiveCardNotify();
			}

			yield return new WaitForSeconds(0.5f);
			while(bCheckOtherPlayerCardMoveDone)
				yield return null;

			CompareFinalList(winnerSID);
			CompareFinalList(loserSID);
			//BattleManager.Instance.SetMaxCombatCount(0);
			//BattleManager.Instance.combatCount = 0;	
			battleManagerCombatCount=0;
		}
	}
	
	void ShowActiveCardNotify()
	{
		if( myDeck.activeList.Count>0)
		{
			UnitCard firstcard = myDeck.activeList[0];
			if( firstcard.skill_notify_string != "")
			{
				UIManager.Instance.ShowSkillInfo(   CStringTableManager.Instance.GetItemByName(	firstcard.skill_notify_string) , true );
			}
		}		
	}
	
	public void CompareFinalList(int sid)
	{
		if( StageManagerWrapper.IsNPCSid(sid) )
			return;

		if(!playerDeck.ContainsKey(sid))
			return;		
		
		if( unitActivationInfo[sid].CurCombatInfo().activeList.Count != playerDeck[sid].activeList.Count)
		{
			Debug.LogError(sid+" active list count differ  c="+playerDeck[sid].activeList.Count+"  s="+unitActivationInfo[sid].CurCombatInfo().activeList.Count);
			RearrangeCards(sid);
			unitActivationInfo[sid].SetCurCombatInfoToNormal();
			unitActivationInfo[sid].ClearAllCombatInfo();
			return;
		}

		bool isSlotDiffer = false;
		int i=0;
		foreach( UnitCard card in playerDeck[sid].activeList)
		{
			if(card.slot != unitActivationInfo[sid].CurCombatInfo().activeList[i])
			{
				Debug.LogError(sid+" slot active differ  c="+card.slot+"  s="+unitActivationInfo[sid].CurCombatInfo().activeList[i]);
				isSlotDiffer = true;
			}
			i++;
		}
		
		if( unitActivationInfo[sid].CurCombatInfo().deactiveList.Count != playerDeck[sid].deactiveList.Count)
		{
			Debug.LogError(sid+" deactive list count differ  "+playerDeck[sid].deactiveList.Count+"  "+unitActivationInfo[sid].CurCombatInfo().deactiveList.Count);
			RearrangeCards(sid);
			unitActivationInfo[sid].SetCurCombatInfoToNormal();
			unitActivationInfo[sid].ClearAllCombatInfo();
			return;
		}

		foreach( UnitCard card in playerDeck[sid].deactiveList)
		{
			//if(card.slot != unitActivationInfo[sid].CurCombatInfo().deactiveList[i])
			//	Debug.LogError(sid+" slot deactive differ  "+card.slot+"  "+unitActivationInfo[sid].CurCombatInfo().deactiveList[i]);
			bool checkOK = false;
			foreach( int slot in unitActivationInfo[sid].CurCombatInfo().deactiveList)
			{
				if(card.slot == slot)
				{
					glog.debug(sid+" deactive checkOk "+slot);
					checkOK = true;
					break;
				}
			}
			if(!checkOK)
				Debug.LogError("deactive not exist "+card.slot);
		}

		if(isSlotDiffer)
			RearrangeCards(sid);

	
		if(IsShowDetailDeck(sid))
		{
			i=0;
			foreach( UnitCard card in playerDeck[sid].activeList)
			{
				if(card.nPos != i)
				{
					Debug.LogError("card pos not match .  force move");
					card.SetnPos(i);
					CardMoveNormal(sid,card, 0,0);
				}
				i++;
			}
		}


		unitActivationInfo[sid].SetCurCombatInfoToNormal();
		unitActivationInfo[sid].ClearAllCombatInfo();

	}

	//rearrange cards by server data
	void RearrangeCards(int sid)
	{
		glog.debug("RearrangeCards  "+sid);
		foreach( UnitCard card in playerDeck[sid].activeList)
		{
			if( unitActivationInfo[sid].CurCombatInfo().deactiveList.Contains( card.slot) )
				ActivateCardImmediately(sid,card,false);
		}

		foreach( UnitCard card in playerDeck[sid].deactiveList)
		{
			if( unitActivationInfo[sid].CurCombatInfo().activeList.Contains( card.slot) )
				ActivateCardImmediately(sid,card,true);
		}

		playerDeck[sid].activeList.Clear ();
		int pos=0;
		foreach( int nSlot in unitActivationInfo[sid].CurCombatInfo().activeList)
		{
			foreach( UnitCard card in playerDeck[sid].cards)
			{
				if(card.slot==nSlot)
				{
					ActivateCardImmediately(sid, card, true);
					playerDeck[sid].activeList.Add (card);
					if(card.nPos != pos)
						MoveCardToPos(sid,card, pos);
					break;
				}
			}
			pos++;
		}

		playerDeck[sid].deactiveList.Clear ();
		foreach( int nSlot in unitActivationInfo[sid].CurCombatInfo().deactiveList)
		{
			foreach( UnitCard card in playerDeck[sid].cards)
			{
				if(card.slot==nSlot)
				{
					ActivateCardImmediately(sid, card, false);
					playerDeck[sid].deactiveList.Add (card);
					if(card.nPos != pos)
						MoveCardToPos(sid,card, pos);
					break;
				}
			}
			pos++;
		}
	}

	void ActivateCardImmediately(int sid, UnitCard card, bool bActivate)
	{
		if( IsShowDetailDeck(sid) )
		{
			if(bActivate)
				card.SetActivate(true,0);
			else
			{
				int maxRemainTurn = 3;
				if( unitActivationInfo[sid].CurCombatInfo().deactiveRemainTurn.ContainsKey(card.slot) )
					maxRemainTurn = unitActivationInfo[sid].CurCombatInfo().deactiveRemainTurn[card.slot];
				card.SetActivate(false, maxRemainTurn);
			}
		}
	}

	void MoveCardToPos(int sid, UnitCard card, int newPos)
	{
		if( IsShowDetailDeck(sid) )
		{
			card.SetnPos( newPos);
			CardMoveNormal(sid, card, 0, 0);
		}
		else
		{
			card.SetnPos(newPos);
			SetOtherPlayerCardPos(sid, newPos, card.gameObject);
		}
	}

	public Vector3 FindScrPos(bool isLeft, int sid, MoveDir anchor)
	{
		int nOrder = HudManager.Instance.charSidOrderDic[sid];
		float scaleMod = 1/cardDeck[nOrder].transform.localScale.x;
		float parent_x = cardDeck[nOrder].transform.localPosition.x;
		float parent_y = cardDeck[nOrder].transform.localPosition.y;
		float mid_x = CSceneManager.widthScreen/2.0f;
		float mid_y = CSceneManager.heightScreen/2.0f;
		
		if(anchor == MoveDir.TopLeft || anchor == MoveDir.TopRight)
			mid_y = -mid_y;
		
		if(anchor == MoveDir.TopRight || anchor == MoveDir.BottomRight)
			mid_x = -mid_x;
		
		mid_x = (mid_x-parent_x)*scaleMod;
		mid_y = (mid_y-parent_y)*scaleMod;
		

			
		float offset_x = 230*scaleMod;
		
//		if(anchor == MoveDir.BottomRight || anchor == MoveDir.TopRight)
//			offset_x = -offset_x;
		
		if(isLeft)
			mid_x -= offset_x;
		else
			mid_x += offset_x;
		
		return new Vector3(mid_x,mid_y,0);
	}

	public Vector3 FindScrPosCenter(Vector3 pos)
	{
		Vector3 screenPos = Camera.main.WorldToScreenPoint(pos);

		float x = CSceneManager.widthScreen * (screenPos.x/(float)Screen.width - 0.5f);
		float y = CSceneManager.heightScreen * ( screenPos.y/(float)Screen.height - 0.5f);
		glog.debug("FindScrPosCenter screenPos = "+screenPos+"  x="+x+"  y="+y);
		return new Vector3(x,y,0);
	}
	
	public GameObject GetCardObject(int sid, int slot)
	{
		foreach( UnitCard card in playerDeck[sid].activeList)
		{
			if(card.slot == slot)
				return card.gameObject;
		}
		
		if( playerDeck[sid].curActiveCard != null && playerDeck[sid].curActiveCard.slot == slot)
			return playerDeck[sid].curActiveCard.gameObject;
		
		return null;
	}
	public void ShowPopupCardSkillEffect(int sid)
	{
		if( playerDeck.ContainsKey(sid) )
		{
			if( playerDeck[sid].curActiveCard != null)
			{
				CardSkillEffect( playerDeck[sid].curActiveCard );
			}
		}
	}

	public void ShowPopupCardSkillEffect(int sid, AbnormalType abType)
	{
		if( playerDeck.ContainsKey(sid) )
		{
			if( playerDeck[sid].curActiveCard != null)
			{
				if(playerDeck[sid].curActiveCard.abnormalList.Contains(abType) )
					CardSkillEffect( playerDeck[sid].curActiveCard );
			}
		}
	}

	public void ShowFirstActiveCardSkillEffect(int sid)
	{
		if( playerDeck.ContainsKey(sid) )
		{
			if( playerDeck[sid].activeList.Count>0)
			{
				CardSkillEffect( playerDeck[sid].activeList[0] );
			}
		}
	}

	public void ShowFirstActiveCardSkillEffect(int sid, AbnormalType abType)
	{
		if( playerDeck.ContainsKey(sid) )
		{
			if( playerDeck[sid].activeList.Count>0)
			{
				if(playerDeck[sid].activeList[0].abnormalList.Contains(abType) )
					CardSkillEffect( playerDeck[sid].activeList[0] );
			}
		}
	}

	public void ShowFirstActiveCardSkillEffect(int sid, string passive_skill)
	{
		if( playerDeck.ContainsKey(sid) )
		{
			if( playerDeck[sid].activeList.Count>0)
			{
				if(playerDeck[sid].activeList[0].passive_skill == passive_skill )
				{
					if(passive_skill=="card_tile_change_01_bumpy")
						HudManager.Instance.ShowAIEmotionChat(sid, "skill_good");
					CardSkillEffect( playerDeck[sid].activeList[0] );
				}
			}
		}
	}

	public void ShowLastActiveCardSkillEffect(int sid)
	{
		if( playerDeck.ContainsKey(sid) )
		{
			if( playerDeck[sid].activeList.Count>0)
			{
				CardSkillEffect( playerDeck[sid].activeList[playerDeck[sid].activeList.Count-1] );
			}
		}
	}

	public void ShowLastDeactiveCardSkillEffect(int sid)
	{
		if( playerDeck.ContainsKey(sid) )
		{
			if( playerDeck[sid].deactiveList.Count>0)
			{
				CardSkillEffect( playerDeck[sid].deactiveList[playerDeck[sid].deactiveList.Count-1] );
			}
		}
	}

	void CardSkillEffect(UnitCard card)
	{
		if(cardSkillEffectPrefab==null)
			cardSkillEffectPrefab = Resources.Load("Prefabs/FX/FX_CardSkillActive") as GameObject;
		if(cardSkillEffectPrefab!=null)
		{
			foreach( GameObject go in cardSkillEffectList)
			{
				if(!go.activeSelf)
				{
					PlayCardSkillEff(go,card);
					Debug.LogError("Card Skill Effect  recycle");
					return;
				}
			}
			GameObject newGo = Instantiate( cardSkillEffectPrefab) as GameObject;
			PlayCardSkillEff(newGo, card);
			cardSkillEffectList.Add (newGo);
			Debug.LogError("Card Skill Effect  New  listCount="+cardSkillEffectList.Count);
		}
	}

	void PlayCardSkillEff(GameObject go, UnitCard card)
	{
		go.transform.parent = card.transform;
		go.transform.localPosition = cardSkillEffectPrefab.transform.position;
		go.transform.localRotation = cardSkillEffectPrefab.transform.rotation;
		go.transform.localScale = cardSkillEffectPrefab.transform.localScale;
		go.SetActive(true);
		ParticleSystem ps = go.GetComponent<ParticleSystem>();
		ps.Clear();
		float startSize = cardSkillEffectPrefab.GetComponent<ParticleSystem>().startSize;
		startSize = startSize * card.transform.localScale.x; //card.transform.parent.localScale.x;
		if(card.transform.parent!=null)
			startSize = startSize * card.transform.parent.localScale.x;
		ps.startSize = startSize;
		ps.Play();
		StartCoroutine("CoDeactivateEff", go);

	}

	IEnumerator CoDeactivateEff(GameObject go)
	{
		yield return new WaitForSeconds(3.0f);
		go.transform.parent = instance.transform;
		go.SetActive(false);
	}
}
